# Case study: Live Election Results Platform

> Live results for TimesLIVE across the 2016, 2019, and 2021 elections, with more than 200,000 concurrent views at peak. Official IEC results were pulled in as they were released, shown on maps down to every voting district, and served through a CDN and caching at every layer so the site stayed online under election-night traffic. In 2016 it won Best Data Visualisation Project at WAN-IFRA's Digital Media Africa Awards.

- URL: https://www.happen.software/case-studies/live-election-results
- Publisher: Happen Software (https://www.happen.software/)

## At a glance

- **Client**: TimesLIVE
- **Category**: Media · Platforms & portals
- **Running**: 2016–2021
- **Recognition**: Best Data Visualisation · WAN-IFRA 2016
- **Recognition**: Best Data Visualisation Project, WAN-IFRA Digital Media Africa Awards 2016
- **Engagement**: The 2016, 2019, and 2021 elections, on one codebase improved after each
- **Audience**: TimesLIVE readers, on the results site and in maps embedded in articles
- **Data source**: Official results from the IEC, pulled in as they were released
- **Coverage**: Country, provinces, municipalities, wards, and voting districts
- **Pages**: Results map, election comparisons, metro battlegrounds, and a registration checker
- **Peak traffic**: 200,000+ concurrent views, served through a CDN and caching at every layer

## Outcomes

- **200,000+**: Concurrent views at peak, with the site staying fast and online
- **3 elections**: National and municipal, in 2016, 2019, and 2021, on one codebase improved after each
- **8 minutes**: Between each pull of new results from the IEC while counting was under way
- **5 levels**: Of results on the map, from the whole country down to a single voting district

## What the client says

> We have worked on intricate web development projects including our award-winning interactive local and national election data website and our Sunday Times Finders Keepers competition website, and we have always been impressed by the team's technical know-how, seamless project management and expert support. It's a pleasure to work with Happen Software.
>
> Riaan Wolmarans, Arena Africa

## Context

TimesLIVE is a South African news site, and on election nights a large share of the country turns to it for results. Those results are published by the IEC, the electoral commission, district by district as the count goes on.

We built TimesLIVE's results site for the 2016 municipal elections, then ran it for the 2019 national and 2021 municipal elections, improving the same codebase after each one. By 2021 it pulled results from the IEC as they were released, drew them on maps down to every voting district, set them against past elections, and served more than 200,000 concurrent views at peak.

## The challenge

- **Everyone arrives at once**: Traffic peaks on election night and as results come in, exactly when the site is most visible and can least afford to slow down or go offline.
- **Results as they're released**: Figures change throughout the count across thousands of voting districts, and readers expect to see them soon after the IEC publishes them.
- **Visuals that stand apart**: Every news site carries the same official numbers, so the results had to be shown in a way readers couldn't get anywhere else.

## Before and after

| Area | Without it | With the results site |
|---|---|---|
| Seeing results | Official figures read as tables of numbers. | A map shaded by the leading party and the strength of its lead, down to each voting district. |
| Keeping up | Readers refreshing to find out what's changed. | New results pulled from the IEC every 8 minutes during the count, with caches refreshed after each update. |
| Traffic | Every reader's request reaching the database. | Responses cached at the CDN, in the browser, and on the server, with compressed map shapes served as static files. |
| Context | Each result read on its own. | Any area compared with past elections back to 2009, with the change for each party. |
| Close races | Metro contests hard to follow as the count goes on. | Battleground pages for the top metros, with each party's share charted over the count. |
| Before the vote | Voters unsure whether they're registered in the right place. | A registration checker that matches a home address and ID number against the IEC's records. |

## Election night, end to end

1. **Prepare**: Boundaries for every province, municipality, ward, and voting district are converted from GeoJSON into compact TopoJSON files, and parties and past results are loaded from the IEC, so the map is ready before the first vote is counted.
2. **Register**: In the weeks before the vote, readers enter their home address and ID number to check that they're registered in the voting district where they live.
3. **Count**: Every 8 minutes, results for voting districts still being counted are fetched from the IEC in parallel, then for wards, municipalities, provinces, and the country, with each run logged.
4. **Refresh**: When a results update finishes, the server cache for that election is cleared, and a snapshot of each municipality's results is saved for the charts that show the count over time.
5. **Serve**: Requests go through the CDN, readers' browsers keep responses for a short time, repeat requests are answered from the shared server cache, and map shapes and party logos are static files cached for weeks.
6. **Explore**: Readers drill from the country to their own voting district, switch to a cluster view of voting stations, compare past elections, or follow the metro battlegrounds, on the site or embedded in articles.

## What we built

- **Results map**: Every area is shaded in the leading party's colour, lighter or darker by its share of the vote. Readers drill down from the country to a single voting district, or type their address to jump straight to their own.
- **Voting station clusters**: A second map view groups the results of individual voting stations into a grid, so patterns inside a municipality or ward show up at a glance.
- **Compare elections**: Any area's results set against national, provincial, and municipal elections back to 2009, with charts of how each party's share changed by year and by party.
- **Metro battlegrounds**: The top metros on one page, with each party's share charted as votes were counted, the change since 2016, and vote shares across past elections.
- **Live IEC results**: Official ballot and seat results pulled from the IEC's results service on a schedule, from voting districts up to the whole country, with the progress of the count for each area.
- **Caching at every layer**: A CDN in front of the site, browser caching, a shared server cache keyed by each request, and long-lived static files for compressed map shapes and logos, so most requests never reach the database.
- **Registration checker**: Before the vote, readers enter their address and ID number to find out whether they're registered in the voting district where they live, and what to do if they're not.
- **Embeds & news**: Maps and battleground pages can be embedded in TimesLIVE articles without the site's navigation, and the latest TimesLIVE election coverage is shown alongside the results, refreshed every 2 minutes.

## What each team gets

### Readers

- Results for their own voting district
- A map shaded by party and strength of lead
- Each result set against past elections

### Journalists & editors

- Maps and charts to embed in articles
- Metro battlegrounds charted over the count
- Changes since the last election, by party

### Voters before the vote

- A check that they're registered in the right place
- Their voting district found from their address
- Clear next steps if their registration is wrong

### TimesLIVE

- A results site in its own look and header
- Its latest election coverage beside the results
- A site that stayed online on the busiest nights

## How it was delivered

- **2016, First election**: Our first results site for TimesLIVE, built for the 2016 municipal elections.
- **2019, National elections**: Results for the national and provincial elections on the same codebase, improved after what we learned in 2016.
- **2021, Improved again**: From March, for the November municipal elections: the registration checker, results to voting-district level, comparisons back to 2009, metro battlegrounds, compressed map shapes, and reworked caching.
- **November 2021, Election week**: A live banner switched on for the count, fixes to the battlegrounds on mobile, and automatic refreshing switched off once counting ended.

## Engineering

- Caching at every layer: Cloudflare's CDN, short-lived browser caching, a shared server cache stored in binary rather than JSON, and static map shapes and logos cached for 30 days. Past elections never change, so their results are cached for up to 10 days.
- The server cache for the live election is cleared as soon as each results update finishes, so readers get new figures quickly without every request being worked out again.
- Each sync fetches only the voting districts whose counts aren't complete, in parallel, then rolls up through wards, municipalities, and provinces, and logs the time taken and the IEC's response times at every level.
- Map boundaries are converted from GeoJSON to TopoJSON, which stores each shared border once, with coordinates cut to five decimal places and a static file for each area. Results go out as compact arrays, so the API sends far less and the heaviest data is never generated on demand.
- For national elections, seats are calculated from the votes counted so far, then replaced by the IEC's own allocation once counting is complete.
- Syncing, caching, and the live banner are all settings, so behaviour on the night could be changed without a redeployment.

Stack: .NET, ASP.NET Core, SQL Server, Angular, Ionic, Leaflet, TopoJSON, Chart.js, Cloudflare

## Get in touch

Expecting your busiest day online? We'll talk through how to keep a site fast and online when everyone arrives at once, and how to turn live data into visuals people come back for. Book a free 30-minute call with one of our engineers.

Contact: https://www.happen.software/contact or sales@happen.software
