Engineering for the school year: freezes, sandboxes and support
The practices that separate a K-12 product districts keep from one they survive: tenancy, sandboxes, per-district observability, freezes.
Everything in this series has been about building the right thing. This is about running it, for years, across many districts, without operational load growing faster than the customer base.
The organising idea is simple and rarely acted on: the school year is your release calendar, your support plan and your risk model, and it isn't negotiable.
The release calendar
Districts' tolerance for change varies across the year by roughly an order of magnitude.
| Window | What it is | What belongs here |
|---|---|---|
| Jul to Aug | Rollover | Nothing new. Rostering work must be finished and rehearsed before this |
| September | Start of year | Fixes only. Highest support load, lowest appetite for change |
| Oct to Dec | The working window | Schema migrations, infrastructure changes, significant features |
| Jan to Mar | Renewal season | Stability. Your usage reporting has to answer whether the thing is being used |
| Mar to May | Testing freeze | State assessment windows. Plan a freeze; you won't be given a choice |
| May to Jun | Close and prepare | Fiscal year end, and the summer build for a year starting in six weeks |
Two things fall out immediately.
Your riskiest work belongs in October and November. Usage is high enough to find problems and tolerance is high enough to absorb them.
Your highest support capacity is needed in the three weeks when your usage numbers are lowest. The start of the year, when everything is being set up and nothing is being used yet.
One note on the freeze: assessment windows differ by state, so a national product has a rolling freeze rather than a single one, and needs to know which districts are currently in theirs.
Multi-tenancy and isolation
A district is a tenant, and the isolation boundary needs to be real enough to describe in a security review.
Tenancy is keyed properly. For LTI, on iss + client_id + deployment_id, never iss alone. Two districts on the same regional LMS instance must not share a tenant.
Every query is scoped, structurally. Row-level security, a scoped repository layer, or schema per tenant. Something that makes the unscoped query hard to write by accident, because "the developer remembers the where clause" isn't an answer to "how do you ensure district A can't see district B's data".
Deletion is per-tenant and complete. Enumerated across every store, including analytics, logs, support attachments and backups, producing evidence.
Configuration is per-tenant and includes retention period, jurisdiction, enabled features, roster source, accommodation defaults, and anything a district negotiated. Held as data, versioned, auditable. Never a code branch, never an environment variable.
Feature flags are per-district. A district that piloted something and wants it off. A district on an older workflow while they retrain staff. A district needing a fix ahead of everyone else. Without per-tenant flags this becomes forked deployments, and forked deployments are how a small team stops being able to ship.
Give every district a sandbox
Three internal environments is table stakes. The one missing from most K-12 products is the fourth: a sandbox the district's own administrator can test in.
A district technology director asked to approve your integration wants to connect their roster feed, launch from their LMS, and confirm grades reach their gradebook, without touching live student data.
If they can't, they'll test in production during the first week of school, which is the worst possible time and place.
Give them a non-production tenant, a documented test roster, and a way to verify each integration point independently. It converts the riskiest week of your year into a rehearsal in July.
Observability the district can use
Aggregate metrics don't answer the only question that matters operationally: is this specific district okay right now?
Per district, continuously: last successful roster sync and its outcome, roster validation results, active users against expected users, passback success rate, error rate for their tenant, and any job stuck or quarantined.
Then two things most teams skip.
Make it visible to the district. A status page for their tenant their own administrator can read. This cuts tickets substantially, and when a problem is genuinely on their side, an expired credential or a changed sharing setting, they find it before you do.
Alert on the district-shaped failure, not the system-shaped one. "Error rate up 2%" is a system alert. "District 4412's roster sync hasn't succeeded in 36 hours" is the alert that prevents a phone call. Most K-12 incidents are single tenant and invisible in aggregate.
Support that runs on school time
Support in this market has a shape most SaaS support doesn't.
It's time-boxed to school hours across time zones. A teacher's problem is urgent between 08:00 and 15:00 local and irrelevant at 19:00. A national product needs coverage from early Eastern to late Pacific.
It's concentrated. The first three weeks of September, and the week before grades close each period. Staff for the peak or plan explicitly to degrade.
The reporter is rarely the person who can fix it. A teacher reports a rostering problem that the district's SIS administrator has to resolve. Your support has to tell the difference and route it, ideally with evidence. That's why the staged payloads from a roster sync that survives the school year and the passback support view from grade passback that lands are operational features rather than conveniences.
Escalation to the district needs a defined path. Named contacts, known response expectations, and a route that isn't the general support inbox. That includes the safeguarding escalation from COPPA, PPRA and consent in schools.
Four data operations nobody plans for
They'll exist whether or not you design them, and they're much better designed.
The deletion job. Runs on a schedule, honours per-district retention, covers every store, produces evidence. Required by contract, by state law, and by the 2025 COPPA amendments.
The backfill. Recomputing something across every district. It will happen. Make it chunked, resumable, rate-limited per tenant, and observable. An unbounded backfill saturating the database at 08:15 Eastern is a self-inflicted outage during first period.
The re-key. A district migrates SIS and every external identifier changes. Dry run, report of matched, ambiguous and unmatched, human approval before commit. Build it before you need it.
The export. Per-district and per-student, readable, complete. Needed at termination, needed for a parent request, and needed sooner than anyone plans for.
What good looks like
A well run K-12 platform has a recognisable profile.
Roster health is visible per district, to the district. Rollover is rehearsed in June rather than survived in August. The riskiest changes ship in November. There's a spring change freeze everyone knows about. Every district has a sandbox. Deletion, export and re-key are ordinary operations rather than projects. Support is staffed for September and reachable in school hours. The security review pack is current because it's maintained rather than assembled.
None of that shows up in a demo. All of it is what a district means when they say a vendor is easy to work with, and that phrase, more than any feature, is what gets you the second contract and the reference call that brings the third.
That's the end of the series. It starts with the second list, the five gates between a good demo and a signed contract.
Common questions
- When should EdTech companies avoid shipping updates?
- During rollover in July and August, during the first weeks of September when support load peaks, and during spring state testing windows. October and November carry the highest tolerance for risky changes, which is where schema migrations and major features belong.
- What is a state testing freeze?
- A period during spring state assessment windows when districts do not want releases, interface changes or new sign-in flows anywhere near a proctored test. Windows differ by state, so a national product has a rolling freeze and needs to know which districts are currently in theirs.
- How should a K-12 platform handle multi-tenancy?
- Key tenancy on the LTI issuer, client id and deployment id together rather than the issuer alone, since one platform can host several districts. Scope every query structurally, keep configuration and feature flags per district, and make per-tenant deletion complete and evidenced.