
From a Photo of an Overflowing Bin to a Truck Route: Building SmartWaste on AWS
How I built SmartWaste, a serverless AWS app for the WeMakeDevs x AWS "Ship It" hackathon. Residents photograph overfull bins in Bhubaneswar, a cloud pipeline estimates fill levels and forecasts overflow, and a nightly workflow plans the shortest truck route that reaches the urgent bins first. This is the full build journey, including what is real, what is not, and what comes next.

From a Photo of an Overflowing Bin to a Truck Route: Building SmartWaste on AWS
How I built SmartWaste, a serverless AWS app for the WeMakeDevs x AWS "Ship It" hackathon. Residents photograph overfull bins in Bhubaneswar, a cloud pipeline estimates fill levels and forecasts overflow, and a nightly workflow plans the shortest truck route that reaches the urgent bins first. This is the full build journey, including what is real, what is not, and what comes next.
| |
|---|---|
Built for | WeMakeDevs x AWS "Ship It" hackathon |
Deployed in | ap-south-1 , fully serverless |
Code | github.com/AnonCoder06/SmartWaste |
Live demo | Open SmartWaste |
The Problem I Kept Walking Past
In Bhubaneswar, a lot of the garbage ends up at bus stops. You see the same overflowing bin at the same stop, and you realize nobody who could empty it knows it is full. Meanwhile, collection trucks follow routes that also visit bins that are barely half full.
So there are two problems with one root cause: the information never reaches the people who decide.
Residents see the bins but cannot tell anyone. Crews make the decisions but cannot see the bins. SmartWaste is my attempt to close that gap. A resident photographs a bin, the cloud estimates how full it is, and every night a planner builds the truck's route, with the most urgent bins first.
✍️ [My Personal Note: the moment you first noticed this problem, or why you picked it for the hackathon]
The system at a glance

SmartWaste on AWS (simplified). A resident's report flows along the top, and the nightly planner runs along the bottom. Both lanes meet in DynamoDB.
Step 1: Start with the Experience, Not the Cloud
I began with a front end, not an architecture diagram. The first version was a single HTML landing page with a split-screen gateway. On the left is Report & Upload for residents and volunteers. On the right is Field Operations & Dispatch for collectors. Hover over a side and it widens, and click and it expands into a workspace.

I started here because the whole product comes down to two people looking at the same bins from different sides. Getting the two workspaces right early meant every backend decision had a clear purpose.
Step 2: Make the Data Feel Real
A map of fake dots does not feel like a product, so I mapped the 24 seeded bins to named Mo Bus stop coordinates in Bhubaneswar. Marker names show on hover or keyboard focus. In the cloud version, Amazon Location Service draws the basemap and Amazon Location Routes returns road-following geometry between the ordered stops.

The offline demo map. Colour shows how full each bin is now, and the dashed ring shows where it is predicted to be by morning. Hover over a marker to see the stop's name.
✍️ [My Personal Note: a map or coordinates problem you ran into, e.g. matching stops like KIIT Square, Patia Square or Damana Square]
Step 3: The Photo Pipeline (and Why It Is Asynchronous)
A resident should not wait on a slow request just to report a bin, so the flow works like this:
- The page asks the API for an upload slot.
- The API creates a pending report in DynamoDB and returns an S3 pre-signed POST. The key, content type and an 8 MB size cap are fixed in the URL.
- The browser uploads straight to a private S3 bucket.
- S3 sends an
ObjectCreatedevent to Amazon SQS.
- An analyzer Lambda picks it up, checks the photo with Amazon Rekognition, estimates the fill level, and updates the bin.
- The page polls until the report reads
done.

A few small decisions here matter:
- Photos that are not bins are rejected with a reason, and the bin is left untouched.
- A photo that fails three times lands in a dead-letter queue and raises an alarm.
- Updates use an optimistic version check, so two simultaneous reports cannot silently overwrite each other.
- A wrong detection can be corrected in one tap, and the correction replaces the original report instead of stacking on top of it.
✍️ [My Personal Note: the bug that cost you the most time, maybe the S3 to SQS to Lambda wiring, a permissions error, or Pillow packaging in a Lambda layer]
Step 4: Being Honest About "AI"
The fill estimate is not a trained model. It measures edge density on a 64x64 grayscale thumbnail, which separates empty, half-full and overflowing bins in clean photos. I wired in an optional Amazon SageMaker hook that is tested against a stub, but I never deployed a model, because I had no labelled bin photos to train one.
I decided early to say so plainly, in the README and here. A baseline you describe honestly is more useful than a model you imply exists. It also gave me a clear next step: collect real labelled photos.
Step 5: Forecasting, Then Planning
The forecast is simple:
text
predicted fill = current fill + fill rate x hours until collection
If it crosses 100%, the system publishes an
OverflowRisk event through Amazon EventBridge and Amazon SNS notifies the crew.The planner runs as an AWS Step Functions Express workflow, triggered by EventBridge at 22:00 IST:
text
Load -> Score -> Select within truck capacity -> (any stops?) -> Optimise route -> Save plan
Bins are scored by urgency, low-priority ones are skipped, and stops are picked in priority order until the truck is full. If nothing needs collecting, the workflow skips route optimisation and saves an empty plan. The collector console can run the same workflow on demand and gets the plan back synchronously.


One planner run in the offline demo: 9 of the 24 bins are collected, the 5.7 km route is 3.3 km shorter than visiting all 24, and every bin forecast to overflow by morning is covered.
Step 6: The Test I Am Proudest Of
The planning logic exists twice: in JavaScript (
engine.js ) so the browser demo works offline, and in Python so the Lambda can run it in the cloud. Two copies can drift apart quietly, so I wrote test_parity.py . It runs both versions on five scenarios and requires identical bin scores, route order, distances and capacity decisions. That way the browser and the cloud can never disagree about the plan.
Step 7: Make It Shippable and Watchable
The whole stack is one AWS CDK app in TypeScript, deployed with a single
scripts/deploy.sh . It builds the Pillow layer, bootstraps CDK, deploys, prints the live URL and runs a smoke test. The system has no servers, no VPC, no NAT and no CloudFront. The static site is served straight from Amazon S3 over HTTPS, and API Gateway throttles at 50 requests per second.For observability, there is an Amazon CloudWatch dashboard and four alarms covering the API, the photo pipeline and the planner. I also built a local dev server that runs the real Lambda handlers against in-memory stand-ins for DynamoDB, S3, Step Functions and Rekognition, so I could iterate without touching AWS. Browser tests with Playwright cover the edge cases.
✍️ [My Personal Note: a deployment surprise, like a region quirk, a CDK bootstrap hiccup, or what the first successful live run felt like]
What SmartWaste Is Not (Yet)
- One demo neighborhood, with 24 bins.
- No trained model. The fill estimate is an edge-density baseline.
- No login. Anyone with the link can report, change planner settings and reset demo data, so it should not hold sensitive data or run private operations until access control is added.
- A real-bin photo through the live UI still needs to be verified end to end. The smoke test's synthetic photo was correctly rejected as "not a bin".
What I Would Do Next
- Collect real labelled bin photos and train the SageMaker model.
- Add Amazon Cognito-based access control for reporters and collectors.
- Let fill levels grow between reports, instead of only changing when someone uploads a photo.
- Test plans with real crews and real constraints.
What I Learned
Smarter waste collection is not only a routing problem. It starts with reliable information from the community, turns that into priorities, and ends with a plan a crew can act on. The routing is the easy part. Getting trustworthy information into the system is the hard part.
Code: github.com/AnonCoder06/SmartWaste
Live demo: smartwaste-site-366008914124-ap-south-1.s3.ap-south-1.amazonaws.com
Tags
aws serverless hackathon smartwaste wastemanagement smartcity lambda stepfunctions dynamodb s3 rekognition sagemaker eventbridge cdk python buildinpublic Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article