Snagbook · Engineering · System map

How Snagbook fits together

Snagbook is the app building contractors use to record defects on site and send the client a report. Ten boxes make it run: eight we operate and two outside services we call. This page shows how a request moves through them and why each one is there.

Drawn by Ines Halvorsen, backendChecked against production Tuesday 10 November 2026For new engineers and partner tech leads

CLIENTS APPLICATION DATA BACKGROUND WORK OUTSIDE SERVICES HTTPS HTTPS photos upload directly WEB APPoffice staff, in a browser MOBILE APPinspectors, works offline API3 identical instancesbehind a load balancer CACHEsessions, rate limits DATABASEprimary + read replica JOB QUEUEslow work, waiting its turn WORKERS2 instances FILE STORAGEphotos and PDFs EMAILdelivery service PUSHnotification service 1 2 3 4 5 6 7 8 9 HTTPS HTTPS photos upload directly WEB APPoffice staff,in a browser MOBILE APPinspectors,works offline API3 identical instances behind a load balancer CACHEsessions,rate limits DATABASEprimary +read replica JOB QUEUEslow work,waiting its turn WORKERS2 instances, doing the background work FILE STORAGEphotosand PDFs EMAILdeliveryservice PUSHnotificationservice 1 2 3 4 5 6 7 8 9 9

One finished inspection, step by step

The numbers match the dots on the diagram. An inspector walks a site, taps Finish, and the client gets a report.

  1. During the walk, the mobile app sends each photo straight to file storage, using an upload link the API signed. A link works for 10 minutes.
  2. On Finish, the app sends the inspection to the API: the defects, their locations and the names of the photos.
  3. The API looks up the session in the cache to see who is asking.
  4. It saves the inspection to the database.
  5. It adds a “build report” job to the queue and answers the phone at once: accepted. Nobody waits on a PDF.
  6. A worker takes the job off the queue.
  7. The worker reads the inspection from the database.
  8. It builds the PDF and writes it to file storage. A 40-photo report takes about 20 seconds.
  9. It asks the email service to send the client a link, and the push service to tell the inspector the report has gone.

The parts, and why each is there

Web app

What office staff use in a browser: scheduling inspections, reading reports, keeping the client list. It holds no data of its own. Every screen is a request to the API.

Mobile app

What inspectors carry. Sites often have no signal, so it keeps an inspection on the phone and sends it when it can. That is why step 2 can arrive hours after the walk.

API

The only door to the data. Three identical instances keep nothing in memory between requests, so any one can answer any request and we deploy by swapping them one at a time.

Cache

A fast key-value store for sessions, rate-limit counters and each company's checklist templates, kept for 5 minutes. It spares the database the most frequent questions. Wipe it and everyone signs in again; nothing else is lost.

Database

The record of everything: companies, sites, inspections, defects. The primary takes every write and a read replica serves the heavy report queries. Backed up nightly, kept for 30 days.

Job queue

A waiting line for slow work. It lets the API say yes in milliseconds and leave the PDF for later. A job that fails is retried 5 times, waiting longer each time, then set aside for a person.

Workers

Two instances that take jobs from the queue: building PDFs, resizing photos, sending email. They are separate from the API so a burst of reports on a Friday afternoon can't slow the app down.

File storage

Photos and finished PDFs. Phones upload to it directly, so a 6 MB photo never passes through the API. Clients download reports through links that stop working after 7 days.

Email and push

The two outside services. Only the workers call them, never the API. When a provider is slow, a job waits and no person does.

Left off on purpose: logging, monitoring and the deploy pipeline. They touch every box and would hide the picture, so they have their own page. If you change how two boxes talk to each other, change this page in the same pull request.

Sample page. The names and numbers are made up.