Skip to content

django-countdown

Announce planned Django downtime before it starts, then close the site cleanly while it happens — without locking yourself out.

django-countdown gives you two things that work together:

  1. A countdown banner injected into your own templates, with a live JS timer counting down to the moment the site closes.
  2. A blocking middleware that returns HTTP 503 and renders a branded maintenance page once that moment arrives — except for superusers, who keep browsing so they can finish the work.

Everything is driven by a single database row per Site, which you create from the Django admin or with one command:

$ ./manage.py start_countdown --banner +15m --service +30m \
      --message "Database upgrade" --noinput
✓ Created countdown for example.com.

There is a command for every other verb too — because the moment you need them, the site is usually already closed and the plan is already slipping:

$ ./manage.py show_countdown       # which phase, and how long left?
$ ./manage.py extend_countdown     # it is taking longer than planned
$ ./manage.py shorten_countdown    # it is going faster
$ ./manage.py stop_countdown       # done — reopen the site

Why it exists

Planned downtime is the worst kind of downtime to communicate badly. Users land on a half-broken page mid-deploy, hit error logs, file support tickets, and trust erodes. Announcing the window in advance and serving an honest 503 during it turns an incident into a non-event.

Features

  • Pre-maintenance banner

    An ultra-visible banner with a timer that ticks live, injected through a context processor and included wherever you want it.

  • Hard cutoff at expiry

    Middleware returns HTTP 503 and renders a maintenance page the moment the countdown lapses — a status code that proxies and crawlers understand.

  • Superuser bypass

    Admins keep working through the cutoff so they can finish the job and clear the countdown.

  • Bounded or indefinite windows

    Set maintenance_until for auto-recovery, or leave it empty to stay blocked until someone explicitly unblocks.

  • Per-Site configuration

    One countdown per domain via django.contrib.sites — multi-tenant projects close one site without touching the rest.

  • Translatable

    Every user-visible string goes through gettext; English and Polish catalogs ship with the package.

Where to go next

I want to… Read
Install and wire it into settings Installation
See a countdown running in three minutes Quickstart
Understand who sees what, and when How it works
Restyle the maintenance page Blocked page
Script downtime from CI or a deploy hook Scheduling a countdown
Check on, adjust or end a window already running Managing a running countdown
Look up a field, setting or template block Reference

Requirements

Django 3.10 3.11 3.12 3.13 3.14
5.2 LTS
6.0
6.1

All eleven cells run in CI on every push. The only runtime dependency is Django itself.

Licence

MIT — see LICENSE.