This is a backend, see CutSolverFrontend for a human usable version.
This API can be used to solve the common problem of finding the perfect placement of cuts for specified lengths. It seems like no other free service tackles this specific problem in an easy-to-use format, so this is my attempt.
You are very welcome to share how you use this tool!
This Solver is using integers exclusively, as there is no need for arbitrary precision (yet). Feel free to shift your numbers a few decimals if you need fractions. It has no concept of units, so you can use whatever you want.
Nerd talk: This is the 2D "Cutting Stock Problem", which is NP-hard. No algorithm exists to calculate a perfect solution in polynomial time, therefore brute force (perfect solution) is used for small jobs (usually <12 entries) and FFD (fast solution) for larger ones. When multiple solutions yield equal total trimmings, the solver deterministically breaks ties by comparing descending offcut sizes. This prioritizes woodworking scrap utility (favoring fewer, larger reusable offcuts over fragmented scraps) and guarantees deterministic execution under Python 3.13 hash randomization.
Feel free to run manually, but the easiest (and advised) way to deploy this is by using Docker and pulling an up-to-date image.
Send POST-Requests to [localhost]/solve to get your results, see /docs for further information.
Also see example job and result from tests.
Calculate optimal cuts using curl:
curl -s -X POST https://cutsolver.modisch.me/solve \
-H "Content-Type: application/json" \
-d '{
"stocks": [{"length": 1000}],
"required": [{"length": 500, "quantity": 1}],
"cut_width": 5
}'Or via PowerShell:
$body = '{"stocks": [{"length": 1000}], "required": [{"length": 500, "quantity": 1}], "cut_width": 5}'
Invoke-RestMethod -Uri "https://cutsolver.modisch.me/solve" -Method Post -Body $body -ContentType "application/json"You don't need to check out this repository and build your own image, I am pushing prebuild ones to Docker Hub.
Download and start this container by using the provided docker-compose file or
with docker run [--rm -it] -p80:80 modischfabrications/cutsolver:latest.
Note: Replace latest with a version number if you depend on this interface, I can guarantee you that the interface
will change randomly. It's more or less stable since the 1.0 release, but be ready for the unexpected.
Both linux/amd64 and linux/arm64 are currently supported, more will be build whenever I get around to it, message
me if you need another architecture.
If it can run Docker it will probably be able to run CutSolver. 1 vCPU with 500MB RAM should be fine for small workloads.
Runtimes strongly depend on the single-core performance of your CPU.
You can expect 12 entries to be solved after ~1s with bruteforceand <0.1s with FFD for generic desktops, slower on
weaker machines.
Multiple cores won't speed up job time, but will enable efficient solving of parallel jobs.
The thresholds that decide which jobs are solved which way are defined in constants.py and can be passed as env, see docker-compose.yml for details.
Feel free to contact me or make a pull-request if you want to participate.
Sponsoring and/or paid development is also very welcome, feel free to reach out.
Unit tests should be run locally before releasing to save on CI executions!
- Bump the authoritative version string in
app/settings.py(version = "vX.Y.Z"). - Commit your changes and tag manually:
git tag vX.Y.Z git push origin main git push origin vX.Y.Z
GitHub Actions CI will automatically execute the full test suite and build/publish multi-arch Docker images (linux/amd64,linux/arm64) to Docker Hub (modischfabrications/cutsolver:<VERSION>) and GHCR.
Note: 32-bit ARM (linux/arm/v7) is retired.
Run the test suite locally using pipenv:
pipenv run pytest- Import Paths: Make sure your code and test changes preserve
app.*package imports. - Coverage: Run with coverage reporting (baseline ~94% on core solver logic):
pipenv run python -m pytest --durations=5 --cov=app/ --cov-report term-missing
- Type Checking: Run static type verification:
pipenv run python -m mypy app
Prebuilt multi-arch images (linux/amd64,linux/arm64) are published automatically on tag pushes.
To build and run a container locally for development:
docker run --rm -it -p 8000:80 $(docker build -q .)Docker compose is similar, see included files on how to integrate them into your stack.
Everything should be handled by Docker and/or pipenv.
This project uses:
- FastAPI: easy API (this includes much more!)
- Uvicorn: async web server
- more-itertools: higher performance permutations
Also used for development is: