Pašvaldību vēlēšanu IT fiasko: kas nogāja greizi un ko darīt citādi

1. Kas notika un kāpēc izgāzās

Galvenais trūkumsKo atklāja vēlēšanu nakts
Sasteigta nodošanaSistēma ekspluatācijā tika iedota tikai 1 dienu pirms vēlēšanām – nebija laika pilnai slodzes un drošības pārbaudei.
Nepareizs "rate limiter"Drošības slānis bloķēja likumīgus iecirkņu pieprasījumus, radot ķēdes reakciju un "karoties" serveriem.
Centralizēts OCR mezglsBiļetenu attēli (≈ 100 KB × 600–800 tūkst.) gāja uz vienu galveno serveri; bez paralelizētas apstrādes tas sāka smakt pie pīķa slodzes.
Nav rindas/buferēšanasIecirkņu dati "piedzina" backendu, jo netika izmantoti prioritāri job-queue vai message-brokeri (RabbitMQ/Kafka).
Formāls atbalstsIncidentu eskalācija risinājās WhatsApp čatā, nevis ar 24/7 SOC/monitoringu.
Nereāls budžetsPiešķirtie 1,81 M EUR atļāva MVP, bet ne valsts mēroga, kļūmēm noturīgu sistēmu.

2. Nauda: cik bija un cik objektīvi vajadzēja

PozīcijaIzlietots (2025)Adekvāti kritiskai infrastruktūrai
Analīze + dizains≈ 0,18 M0,30 M
Izstrāde (OCR, API, UI)≈ 0,45 M0,90 M
Serveri + glabātuve≈ 0,27 M0,60 M
Drošības/slodzes testi≈ 0,18 M0,30 M
Apmācība + dokumenti≈ 0,18 M0,25 M
24/7 atbalsts(ietilpa kopbudžetā)0,20 M
Vadība + audits≈ 0,27 M0,40 M
Kopā1,81 M EUR≈ 3,5–4,0 M EUR

Tipiska peļņas marža pie valsts iepirkumiem: 15–30 %. Pie 4 M EUR budžeta uzņēmumam (vai konsorcijam) paliktu 0,6–1,0 M EUR pēc algu un infrastruktūras izmaksu segšanas.

3. Tehniskais skats "kā bija" vs. "kā vajadzēja"

KomponentsFaktiski (iespējams)Ieteicamā prakse
DBViena PostgreSQL/SQL Server instance, bez klasterēšanasKlasterēts PostgreSQL vai Oracle RAC + Redis buferis
Failu glabāšanaNFS diskos, nekompresēti JPG/PDFCeph/S3 ar gzip/zip, checksum + verzionēšana
OCRABBYY/Tesseract uz viena 32 vCPU serveraDocker mikropakalpojumi × 10–20 mezgli (auto-scale)
Rate limitingIP-balstīts slieksnisToken-balstīta kvota, adaptīvs uz slodzi
MonitoringSistēmlogi + manuāls WhatsAppPrometheus + Grafana + Alertmanager, SOC komanda
CI/CDManuāla deploy, vēls integrācijas posmsGitLab CI, IaC (Terraform/Ansible), staging + prod vides
TestsIerobežoti JMeter skriptiGatling/JMeter simulējot 1000 iecirkņu, ≥ 2k requests/s

4. Cik laika vajadzēja

5. Galvenā atbildība

LomaPar ko atbildPiezīme
VDAA (Valsts digitālās attīstības aģentūra)Iepirkums, projektu pārraudzība, ekspluatācijas nodošanaKritiski novērtēja slodzes riskus un termiņus par zemu
VARAM (politiskā uzraudzība)Budžets, termiņu kontrole, starpinstitucionālā koordinācijaAkceptēja nodošanu pēdējā brīdī
CVK (Centrālā vēlēšanu komisija)Lietotāja prasības, sistēmas pieņemšanaPieņēma sistēmu bez pilna ģenerālmēģinājuma validācijas
Galvenais līgumizpildītājs (nosaukums publiski slēpts)Izstrāde, testēšana, atbalstsPieļāva arhitektūras un slodzes dizaina nepilnības
Apakšuzņēmēji (OCR, hosting)Specializētie moduļi, datu centrsNoslēgti "melno kastu" līgumi, trūkst caurspīdības

6. Pieci konkrēti padomi nākamajām vēlēšanām

  1. Budžets ≥ 4 M EUR, ar 20 % rezervi neparedzētam infrastruktūras pieaugumam vēlēšanu nedēļā.
  2. Atvērt mikroservisu arhitektūru, balstītu uz Docker + Kubernetes, lai varētu horizontāli mērogot OCR un API mezglus dažu minūšu laikā.
  3. Pilna slodzes simulācija (≥ 2 k pieprasījumi/s) vismaz 60 dienas pirms vēlēšanām; atkārtot pēc katra koda "major" laidiena.
  4. Neatkarīgs drošības audits un "red-team" tests ar DDoS, SQL-injection, identificācijas zādzību scenārijiem.
  5. 24/7 incidentu pārvaldības centrs ar reālu "runbook": restarti automatizēti, push-paziņojumi iecirkņiem, nevis WhatsApp improvizācija.

Municipal Elections IT Fiasco: What Went Wrong and What to Do Differently

1. What happened and why it failed

Main DeficiencyWhat election night revealed
Rushed handoverThe system was put into operation only 1 day before the elections — no time for full load and security testing.
Incorrect rate limiterThe security layer blocked legitimate precinct requests, causing a chain reaction and server overload.
Centralised OCR nodeBallot images (≈ 100 KB × 600–800 thousand) were routed to a single main server; without parallelised processing it began to choke under peak load.
No queue / bufferingPrecinct data overwhelmed the backend, as no priority job-queues or message brokers (RabbitMQ/Kafka) were in place.
Informal supportIncident escalation happened via WhatsApp chat rather than a 24/7 SOC / monitoring system.
Unrealistic budgetThe allocated 1.81 M EUR was enough for an MVP, but not for a national-scale, fault-tolerant system.

2. Money: what was available vs. what was objectively needed

ItemSpent (2025)Adequate for critical infrastructure
Analysis + design≈ 0.18 M0.30 M
Development (OCR, API, UI)≈ 0.45 M0.90 M
Servers + storage≈ 0.27 M0.60 M
Security / load tests≈ 0.18 M0.30 M
Training + documentation≈ 0.18 M0.25 M
24/7 support(included in total budget)0.20 M
Management + audit≈ 0.27 M0.40 M
Total1.81 M EUR≈ 3.5–4.0 M EUR

Typical profit margin on government contracts: 15–30 %. With a 4 M EUR budget, the company (or consortium) would retain 0.6–1.0 M EUR after covering salaries and infrastructure costs.

3. Technical view: "as it was" vs. "as it should have been"

ComponentActual (likely)Recommended practice
DBSingle PostgreSQL/SQL Server instance, no clusteringClustered PostgreSQL or Oracle RAC + Redis buffer
File storageNFS disks, uncompressed JPG/PDFCeph/S3 with gzip/zip, checksum + versioning
OCRABBYY/Tesseract on a single 32-vCPU serverDocker microservices × 10–20 nodes (auto-scale)
Rate limitingIP-based thresholdToken-based quota, adaptive to load
MonitoringSystem logs + manual WhatsAppPrometheus + Grafana + Alertmanager, SOC team
CI/CDManual deploy, late integration stageGitLab CI, IaC (Terraform/Ansible), staging + prod environments
TestingLimited JMeter scriptsGatling/JMeter simulating 1000 precincts, ≥ 2k requests/s

4. How much time was needed

5. Main responsibility

RoleResponsible forNote
VDAA (State Digital Development Agency)Procurement, project oversight, operational handoverCritically underestimated load risks and deadlines
VARAM (political oversight)Budget, deadline control, inter-institutional coordinationAccepted last-minute handover
CVK (Central Election Commission)User requirements, system acceptanceAccepted the system without full dress-rehearsal validation
Main contractor (name withheld publicly)Development, testing, supportAllowed architectural and load-design deficiencies
Subcontractors (OCR, hosting)Specialised modules, data centreBlack-box contracts, lack of transparency

6. Five concrete recommendations for next elections

  1. Budget ≥ 4 M EUR, with a 20 % reserve for unforeseen infrastructure scaling during election week.
  2. Open microservice architecture based on Docker + Kubernetes, enabling horizontal scaling of OCR and API nodes within minutes.
  3. Full load simulation (≥ 2k requests/s) at least 60 days before elections; repeated after every major code release.
  4. Independent security audit and red-team test covering DDoS, SQL-injection, and identity-theft scenarios.
  5. 24/7 incident management centre with a real runbook: automated restarts, push notifications to precincts — not WhatsApp improvisation.