Building Software During Wartime: Lessons from Ukraine
How power outages, security concerns, and wartime constraints shaped my approach to software architecture.
I build software from Kyiv, Ukraine. We’re at war. That context shapes every technical decision I make.
This isn’t a political post. It’s about how constraints drive better architecture.
The Power Situation
Ukraine gets ~12 hours of electricity per day. Not consecutive. Not predictable.
What that means for development:
- No always-on local hardware — Everything runs on VPS (Hetzner)
- Manual generator management — Charging station requires intervention
- Intermittent connectivity — Architecture must handle disconnects gracefully
Lesson: If your system breaks during a 4-hour power outage, you designed it wrong.
Technical Adaptations
1. VPS-First Architecture My main PC (AMD 7800X3D, RTX 4070Ti) can’t be always-on. So:
- OpenClaw gateway: Hetzner VPS (24/7)
- Databases: SQLite on VPS (not local PostgreSQL)
- Services: Docker containers on VPS
2. State Management Every service assumes it might disappear mid-operation:
- Write-ahead logging for critical state
- Idempotent operations (safe to retry)
- No in-memory-only state
3. Graceful Degradation Example: My AI agent (Klowalski) runs on VPS. When my PC loses power:
- Agent continues autonomous work
- Results saved to shared workspace
- I catch up when power returns
No data loss. No confused state. Just resilience.
Security Mindset
Russian intelligence agencies have demonstrated capability and intent to compromise Ukrainian infrastructure. That’s not paranoia — it’s threat modeling.
Encryption-First Design
Every project starts with:
- TLS everywhere — Even internal services
- At-rest encryption — Sensitive data encrypted on disk
- End-to-end where possible — Trust no intermediary
Example: Memory Chain supports AES-256-GCM for sensitive memories. Even if someone gets the chain file, they can’t read encrypted entries without keys.
Zero-Trust Networking
- Tailscale for SSH — No public SSH ports (removed on Feb 15)
- VPN-only admin panels — Mattermost, Fizzy, etc. not public
- Hardware tokens — YubiKey for critical auth (migration planned)
Lesson: If you’re in a hostile environment, assume every connection is monitored. Design accordingly.
Intermittent Connectivity
Internet in Ukraine is reliable… until it isn’t. Russian attacks target telecom infrastructure.
Offline-First Patterns
1. Local-First Storage
- SQLite databases (work offline, sync later)
- Git for code (commit locally, push when connected)
- Append-only logs (never lose data)
2. Queue-Based Communication Instead of:
await sendEmail(); // Fails if offline
Do:
await emailQueue.add(message); // Always succeeds
// Worker processes queue when connected
3. Conflict-Free Data Design data structures that merge cleanly:
- CRDTs where appropriate
- Timestamp-based conflict resolution
- Append-only chains (Memory Chain does this)
Real Example: Govantazh
Cargo management SaaS built for Ukraine logistics:
- Multi-tenant SQLite — Each tenant’s data is a file
- Email ingestion queue — Gmail parser doesn’t fail on network blips
- Offline dashboard — React 19 with aggressive caching
Works when internet is sketchy. Still ships Monday.
Time Management
War means unpredictable interruptions:
- Air raid sirens
- Power schedule changes
- Mental load
Adaptation: Micro-Commits
I commit code in small chunks:
git commit -m "feat: add user auth" # ❌ Too big
git commit -m "feat: add login form UI" # ✅ Shippable
git commit -m "feat: add auth API route" # ✅ Shippable
git commit -m "feat: connect login to API" # ✅ Shippable
Why? If an air raid interrupts work at 2am, I want shippable state at every commit. Not half-finished features that don’t compile.
Palmer Principle (from my AGENTS.md):
“Always leave a session in a state where future-you understands what happened.”
Same logic. Future-you might be dealing with an air raid. Make their life easier.
Optimizing for Low Resources
VPS specs: Hetzner CAX21 (8GB RAM, 4 vCPU ARM64)
Running:
- OpenClaw gateway (~940MB)
- Mattermost (~120MB)
- Matrix homeserver (~90MB)
- Fizzy Kanban (~260MB)
- Viatex production site (~160MB)
- Traefik reverse proxy (~20MB)
Total: ~1.6GB of ~8GB used
How?
- Alpine Linux containers — Minimal base images
- Aggressive caching — Turbo, pnpm, Docker layers
- Lazy loading — Services start on-demand
- Smart scheduling — Cron jobs during low-usage hours
Lesson: RAM constraints force elegant architecture. Bloat is a choice.
What Ukraine Taught Me
1. Resilience > Features A feature that breaks under stress is worse than no feature. Design for hostile conditions.
2. Offline-First Wins Even in peace, networks fail. Power goes out. Laptops disconnect. Offline-first patterns aren’t “Ukraine-specific” — they’re just good engineering.
3. Constraints Breed Creativity No always-on hardware? Use VPS. No reliable internet? Queue everything. Limited RAM? Optimize ruthlessly.
4. Security Isn’t Optional In peacetime, security is “best practice.” In wartime, it’s survival. But the techniques (encryption, zero-trust, hardware tokens) work everywhere.
5. Ship Small, Ship Often You never know when the next interruption comes. Keep work in shippable state. Micro-commits. Continuous deployment.
Tools I Rely On
- VPS: Hetzner (Germany) — Reliable, ARM64, cheap
- VPN: Tailscale — Zero-config mesh networking
- Backup: Restic + Backblaze — Encrypted off-site backups
- Comms: Matrix — Self-hosted, E2E encrypted
- Auth: YubiKey (planned) — Hardware 2FA
- Monitoring: UptimeRobot — Know when services go down
All chosen for resilience under adversity.
For Developers in Stable Environments
You probably have:
- 24/7 electricity
- Gigabit internet
- No air raids
Lucky you. But don’t let comfort make you lazy.
Ask yourself:
- What happens if AWS has a 6-hour outage?
- What if your database gets compromised?
- Can your users work offline?
Build like Ukraine forced me to build: resilient, encrypted, offline-capable, shippable at every commit.
Not because war is coming to you. Because that’s just better software.
Currently shipping from Kyiv:
- Govantazh (cargo SaaS) — Monday deploy
- Memory Chain (AI agent memory) — Live on Base
- semmy.dev (this site) — Built by my AI agent overnight
All built with 12h/day electricity. All deployed to Hetzner VPS. All designed for hostile conditions.
Slava Ukraini 🇺🇦
If you’re building software in difficult circumstances (war, unstable infrastructure, resource constraints), I’d love to hear about your adaptations. Find me on GitHub or LinkedIn.