DEV Community

Divyakush Punjabi
Divyakush Punjabi

Posted on

The maintenance switch that can't lock you out

Every live platform needs a way to stop taking orders — a payment provider incident, a bad deploy, a data migration you don't want customers writing through. On Saturdays, a food delivery platform taking real payments, that's a single flag. Building it took an afternoon. Getting right the one detail most implementations get wrong took longer.

The mechanism is small on purpose

A kill switch should be boring, because the moment you need it is the moment you have the least patience for cleverness. The whole thing is:

  1. One config flag, read at request time, flippable without a deploy.
  2. One middleware, mounted ahead of every view, that checks it.
  3. One response: a structured 503 Service Unavailable with a Retry-After header.
class MaintenanceMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if platform_paused() and not is_exempt(request.path):
            return JsonResponse(
                {"code": "maintenance", "detail": "Temporarily unavailable"},
                status=503,
                headers={"Retry-After": "120"},
            )
        return self.get_response(request)
Enter fullscreen mode Exit fullscreen mode

(A simplified sketch of the shape, not the production file.)

Each choice there is deliberate. Middleware, not a decorator, because a decorator is opt-in per view, and the one view someone forgets is the one that keeps taking orders. 503, not 500 or 200, because clients, load balancers and crawlers all read 503 as "temporary, come back later" — and Retry-After tells them when. Structured JSON, because the frontend needs to render a maintenance screen, not a generic error toast.

The part that actually matters: what's exempt

A middleware that blocks everything has an obvious flaw. If the admin API that flips the flag sits behind it, turning maintenance on removes your ability to turn it off. You've built a door that locks from the outside with the key still inside.

So the switch needs an exemption list — and the discipline is keeping it narrow:

  • The admin control API, so the switch that turned maintenance on can turn it off.
  • Health checks, so your infrastructure doesn't conclude the service is dead and start restarting it mid-incident.
  • Schema docs — read-only, harmless, and useful while you're debugging.

That's it. Every extra path on that list is a hole in the switch. "Just exempt the partner API too" sounds reasonable right up until the incident is in the partner integration.

Why narrow beats clever

The temptation is to make the switch granular: pause checkout but not browsing, pause one city, pause one restaurant. Some of that is genuinely useful — Saturdays' operator console has separate restaurant holds with different blast radius. But those are operational tools. The platform switch is an emergency brake, and an emergency brake with ten settings is one you'll misconfigure under pressure.

Keep the brake binary and the exemptions minimal. Put the nuance in separate, clearly named controls.

The takeaway

When you build any control that can take a system offline, design the "how do I undo this" path first, and make sure the thing it controls can't affect it. Then keep the list of things that bypass the control as short as you can defend.

The operator console, the restaurant holds, and the rest of how the platform is run day to day are covered in the case study.

👉 Full write-up: www.divyakush.com/projects/saturdays


Divyakush Punjabi — Full-Stack & AI Systems Engineer

🌐 https://www.divyakush.com · 💼 LinkedIn · 💻 GitHub

Top comments (0)