MVP Factory

Blog

Practical insights on building MVPs, choosing the right tech stack, and turning ideas into production-ready apps.

· Krystian Wiewiór

Keyword cannibalization in ASO: a data-driven fix

Deep technical dive into how App Store and Play Store search algorithms handle keyword weighting across title, subtitle, keyword field, and description — with a

ai startup development
· Krystian Wiewiór

Cohort retention curves: the PMF signal in your data

Move beyond vanity metrics with concrete PostgreSQL cohort analysis queries, specific retention benchmarks by app category (Day 1/7/30), the flattening-curve si

ai startup development
· Krystian Wiewiór

Building an LLM gateway that cuts your AI bill by 70%

A technical deep-dive into building a self-hosted LLM proxy layer that sits between your mobile/web clients and model providers — covering model routing and aut

ai startup development
· Krystian Wiewiór

Validating Your Startup Idea with a Landing Page, Waitlist, and Stripe Test Mode in One Weekend

A step-by-step technical walkthrough of wiring up a Next.js landing page with Posthog analytics, a Resend-powered waitlist, and Stripe test-mode checkout to mea

ai startup development
· Krystian Wiewiór

Spot node pool configuration

Deep dive into replacing GitHub-hosted runners with self-hosted runners on AWS/GCP spot instances orchestrated by actions-runner-controller, covering graceful j

ai startup development
· Krystian Wiewiór

SQLite on the server: the single-node architecture handling 100K req/s

SQLite on the server as a PostgreSQL replacement for indie and startup workloads — covering Litestream for continuous S3 replication, WAL mode tuning on ext4/bt

ai startup development
· Krystian Wiewiór

Fine-Tuning Whisper.cpp for On-Device Speech-to-Text in KMP: Quantization Strategies, Audio Preprocessing Pipelines, and the Streaming Architecture That Delivers Real-Time Transcription Without Cloud Costs

Deep technical walkthrough of integrating Whisper.cpp into a Kotlin Multiplatform project using expect/actual declarations for platform-specific audio capture (

ai startup development
· Krystian Wiewiór

Running Vision-Language Models On-Device in Android

Technical deep-dive into running VLMs (LLaVA/MobileVLM-class) on Android — covering the dual-model architecture (CLIP vision encoder + language decoder), INT4/I

ai startup development
· Krystian Wiewiór

Android Baseline Profiles and Macrobenchmark in 2026: Measuring Real Startup Time Improvements Across Dex Layouts, Cloud Profiles, and the ART Compilation Pipeline

Deep dive into how Baseline Profiles actually work under the hood — AOT compilation via cloud profiles vs on-device profile-guided optimization, how dex layout

ai startup development
· Krystian Wiewiór

Structured output from on-device LLMs on Android with GBNF

Move beyond raw text generation to building agentic features with on-device models — covering GBNF grammars for structured JSON output via llama.cpp, function-c

ai startup development
· Krystian Wiewiór

Change data capture replaces polling for mobile sync

Building a CDC-powered sync pipeline using PostgreSQL logical replication slots and Debezium to push granular data changes to mobile clients. Covers WAL decodin

ai startup development
· Krystian Wiewiór

On-Device RAG for Android: Running Embedding Models, Vector Search in SQLite, and the Retrieval Architecture That Keeps Sensitive Data Off the Wire

Build a fully offline retrieval-augmented generation pipeline on Android — quantized embedding models via ONNX Runtime, HNSW vector indexing inside SQLite with

ai startup development
· Krystian Wiewiór

Kotlin Context Parameters in Practice: Replacing Service Locators, Scoping Database Transactions, and the Zero-Boilerplate Patterns That Make Clean Architecture in KMP Actually Clean

Deep dive into Kotlin 2.2's context parameters as an architectural primitive — how they eliminate manual dependency threading across call chains, scope database

ai startup development
· Krystian Wiewiór

JSONB indexing: GIN vs expression indexes for mobile APIs

Deep dive into how mobile backends abuse JSONB columns as a 'schema-free' escape hatch, then suffer catastrophic query performance at scale. Cover GIN index int

ai startup development
· Krystian Wiewiór

PostgreSQL partial indexes: drop your app-layer uniqueness checks

Deep dive into combining partial unique indexes (WHERE deleted_at IS NULL) with deferred constraint checking and tenant-scoped composite indexes to enforce comp

ai startup development
· Krystian Wiewiór

gRPC and Protocol Buffers for Mobile API Backends: Binary Wire Format, Bidirectional Streaming, and the Code Generation Pipeline That Gives You Type-Safe Clients Across Android, iOS, and KMP with 60% Less Payload Than REST+JSON

Deep technical comparison of gRPC vs REST for mobile backends — covering protobuf schema design for mobile-friendly field evolution, gRPC-Web as a fallback for

ai startup development
· Krystian Wiewiór

PostgreSQL advisory locks beat Redis for rate limiting

Using pg_try_advisory_xact_lock with connection pooling (PgBouncer in transaction mode) to implement sliding-window rate limiting directly in PostgreSQL, elimin

ai startup development
· Krystian Wiewiór

Swift 6 + Kotlin coroutines: fixing KMP data races

Deep dive into the real friction points when KMP-exported Kotlin coroutine-based APIs cross into Swift 6's strict concurrency world — how @Sendable closures, gl

ai startup development
· Krystian Wiewiór

Compose Multiplatform's Skia Rendering on iOS: Profiling Metal Shader Compilation Stalls, Texture Atlas Thrashing, and the Platform-Specific Patterns That Actually Hit 120fps on ProMotion

Deep dive into the Skiko/Skia rendering pipeline on iOS — how Compose Multiplatform bypasses UIKit, why first-frame Metal shader compilation causes hitches, how

ai startup development
· Krystian Wiewiór

On-Device LLM Inference via KMP and llama.cpp: Memory-Mapped Model Loading, ANE/NNAPI Accelerator Delegation, and the Thermal Budget Patterns That Make 3B-Parameter Models Production-Ready on Mobile

Build a KMP shared module that wraps llama.cpp through cinterop (iOS) and JNI (Android), covering mmap-based model loading to avoid OOM kills, hardware accelera

ai startup development
Ktor at 50K connections: coroutines vs virtual threads
· Krystian Wiewiór

Ktor at 50K connections: coroutines vs virtual threads

Deep technical comparison of Ktor's coroutine dispatcher vs JVM virtual threads (Project Loom) for high-concurrency mobile backends — thread pinning pitfalls, s

ai startup development
PostgreSQL RLS: your last defense against tenant data leaks
· Krystian Wiewiór

PostgreSQL RLS: your last defense against tenant data leaks

Deep dive into implementing RLS policies as the last line of defense against tenant isolation bugs — covering policy design with current_setting vs session vari

ai startup development
PostgreSQL LISTEN/NOTIFY as a lightweight job queue: replacing Redis for your startup's background tasks
· Krystian Wiewiór

PostgreSQL LISTEN/NOTIFY as a lightweight job queue: replacing Redis for your startup's background tasks

Building a zero-dependency job queue using PostgreSQL's LISTEN/NOTIFY channels with SKIP LOCKED advisory locks, comparing throughput benchmarks against Redis-ba

ai startup development
SQLite WAL Mode, Connection Pooling, and Room's Query Planner: The Mobile Database Performance Patterns That Survive Offline-First at Scale
· Krystian Wiewiór

SQLite WAL Mode, Connection Pooling, and Room's Query Planner: The Mobile Database Performance Patterns That Survive Offline-First at Scale

Deep dive into SQLite's WAL vs DELETE journal modes, how Room's InvalidationTracker triggers unnecessary recomputations, connection pool sizing for concurrent r

ai startup development
Compose stability: the recomposition model senior devs get wrong
· Krystian Wiewiór

Compose stability: the recomposition model senior devs get wrong

Deep dive into how the Compose compiler assigns stability to types, how strong skipping mode (default since Compose Compiler 2.0) changes the old mental model o

ai startup development
· Krystian Wiewiór

Partial Indexes and Expression Indexes in PostgreSQL: The Query Optimization Patterns That Cut Our Mobile API P99 Latency by 80%

Deep dive into PostgreSQL's underused indexing strategies — partial indexes for soft-deleted rows, expression indexes for JSONB fields, covering indexes to enab

ai startup development
· Krystian Wiewiór

Google Rejected My Developer Account So I Filed a Legal Complaint and Won — They Paid 250 EUR

Google rejected my developer account 5 times with zero explanation. I filed an ADR complaint, they reversed the decision and paid 250 EUR. Here is the exact playbook.

android startup mobile development
· Krystian Wiewiór

Recursive CTEs in PostgreSQL: kill N+1 queries in mobile apps

Deep dive into using PostgreSQL recursive common table expressions to efficiently query hierarchical data structures common in mobile apps — threaded comments,

ai startup development
· Krystian Wiewiór

Modular monolith in Kotlin: microservice boundaries without the tax

Step-by-step architecture for structuring a Ktor or Spring Boot backend as a modular monolith using Kotlin's internal modifier, JPMS module-info boundaries, and

ai startup development
· Krystian Wiewiór

HikariCP config (WRONG)

Deep dive into the connection pooling layer between your mobile backend and PostgreSQL — covering HikariCP misconfiguration antipatterns (maxLifetime vs server-

ai startup development
· Krystian Wiewiór

Embedding Local LLMs in Your Mobile App: llama.cpp via KMP, 4-Bit Quantization Tradeoffs, and the Streaming Architecture That Keeps Your UI at 60fps

Practical integration of on-device LLM inference in production mobile apps using KMP bindings to llama.cpp, covering GGUF model selection, Q4_K_M vs Q5_K_S quan

ai startup development
· Krystian Wiewiór

Row-level security in PostgreSQL: SaaS tenant isolation without query changes

Implementing PostgreSQL RLS policies with JWT-based tenant context using set_config/current_setting, combining it with connection pooling (PgBouncer in transact

ai startup development
· Krystian Wiewiór

Server-Sent Events as Your Mobile Real-Time Layer: Automatic Reconnection, Last-Event-ID Recovery, and Why SSE on Ktor Replaces 90% of Your WebSocket Use Cases

Deep dive into implementing SSE with Ktor for mobile backends — covering EventSource protocol semantics, Last-Event-ID replay for offline recovery, backpressure

ai startup development
Kotlin coroutines meet Swift 6 concurrency in KMP
· Krystian Wiewiór

Kotlin coroutines meet Swift 6 concurrency in KMP

Deep dive into how Kotlin coroutines map to Swift's async/await at the KMP boundary — covering SKIE vs KMP-NativeCoroutines, handling cancellation propagation a

ai startup development
Zero-downtime PostgreSQL migrations at scale
· Krystian Wiewiór

Zero-downtime PostgreSQL migrations at scale

Deep dive into non-blocking schema migrations for PostgreSQL — covering advisory lock strategies to coordinate migration runners, the ghost table pattern (used

ai startup development
Designing Idempotent APIs for Mobile Clients: Retry Logic, Idempotency Keys, and the Patterns That Prevent Double Charges
· Krystian Wiewiór

Designing Idempotent APIs for Mobile Clients: Retry Logic, Idempotency Keys, and the Patterns That Prevent Double Charges

Deep dive into implementing database-backed idempotency keys in Ktor/Spring Boot, client-side retry strategies with exponential backoff and jitter for unreliabl

ai startup development
Partial indexes in PostgreSQL: wins your mobile backend misses
· Krystian Wiewiór

Partial indexes in PostgreSQL: wins your mobile backend misses

Deep dive into PostgreSQL partial indexes (CREATE INDEX ... WHERE), expression indexes, and covering indexes (INCLUDE) — showing how targeted indexing strategie

ai startup development
· Krystian Wiewiór

Gradle at scale: how we cut KMP CI from 45 to 12 min

Deep dive into Gradle configuration cache compatibility in multi-module KMP projects, build cache hit optimization with remote caching (Develocity/Gradle Enterp

ai startup development
· Krystian Wiewiór

SQLite as your server database: a production guide

Deep dive into using SQLite as a production server database for early-stage startups — covering WAL mode configuration, critical PRAGMA settings (journal_mode,

ai startup development
Replacing Your Message Queue with PostgreSQL: LISTEN/NOTIFY, SKIP LOCKED Queues, and When Kafka Is Overkill for Your Startup
· Krystian Wiewiór

Replacing Your Message Queue with PostgreSQL: LISTEN/NOTIFY, SKIP LOCKED Queues, and When Kafka Is Overkill for Your Startup

Deep dive into using PostgreSQL as a lightweight job queue and event bus using LISTEN/NOTIFY for pub/sub, FOR UPDATE SKIP LOCKED for reliable worker queues, and

ai startup development
· Krystian Wiewiór

The Modularization Trap: When Clean Architecture Becomes Your Startup's Bottleneck

A pragmatic breakdown of how over-modularized Android/KMP codebases create exponential Gradle build times, circular dependency nightmares, and onboarding fricti

ai startup development
Local RAG on mobile: vector search under 200ms
· Krystian Wiewiór

Local RAG on mobile: vector search under 200ms

Implementing a fully offline retrieval-augmented generation system using sqlite-vss for vector similarity search, ONNX Runtime for on-device embedding generatio

ai startup development
Connection pool tuning: HikariCP defaults kill mobile backends
· Krystian Wiewiór

Connection pool tuning: HikariCP defaults kill mobile backends

Deep dive into why the default HikariCP pool size formula (connections = CPU cores * 2 + 1) breaks down for mobile backends with bursty traffic patterns, how to

ai startup development
End-to-End Kotlin: Sharing Type-Safe API Contracts Between Ktor and Compose Multiplatform with Kotlinx.Serialization and Ktor Resources
· Krystian Wiewiór

End-to-End Kotlin: Sharing Type-Safe API Contracts Between Ktor and Compose Multiplatform with Kotlinx.Serialization and Ktor Resources

Building a shared KMP module that defines your entire API surface — routes, request/response DTOs, validation rules, and error types — consumed identically by y

ai startup development
Zero-downtime PostgreSQL migrations at scale
· Krystian Wiewiór

Zero-downtime PostgreSQL migrations at scale

Deep dive into the specific PostgreSQL migration patterns (CREATE INDEX CONCURRENTLY, advisory locks, gh-ost-style shadow table swaps, and NOT VALID constraint

ai startup development
Bridging Kotlin Coroutines and Swift 6 Structured Concurrency in KMP: Building Leak-Free Shared Async APIs
· Krystian Wiewiór

Bridging Kotlin Coroutines and Swift 6 Structured Concurrency in KMP: Building Leak-Free Shared Async APIs

How to design KMP shared modules that expose idiomatic async APIs on both platforms — using SKIE and custom expect/actual patterns to map Kotlin Flows to AsyncS

ai startup development
Advanced Claude Code CLI skills that actually change how you work
· Krystian Wiewiór

Advanced Claude Code CLI skills that actually change how you work

Practical Claude Code CLI techniques for senior engineers: slash commands, MCP servers, custom hooks, and multi-file editing patterns that replace entire toolch

ai startup development
Connection pooling for serverless mobile backends
· Krystian Wiewiór

Connection pooling for serverless mobile backends

Deep dive into how serverless functions (Lambda, Cloud Run, edge workers) interact with PostgreSQL connection limits, comparing transaction-mode PgBouncer, Supa

ai startup development
MCP in Practice: Connecting Claude to Jira, Excel, and Building Multi-Agent Workflows in Minutes
· Krystian Wiewiór

MCP in Practice: Connecting Claude to Jira, Excel, and Building Multi-Agent Workflows in Minutes

How Model Context Protocol turns Claude into a Jira analytics engine — connecting via MCP connector, building agent teams, extracting Lead Time, sprint data, an

ai startup development
OpenCode vs Claude Code: free agentic coding setup
· Krystian Wiewiór

OpenCode vs Claude Code: free agentic coding setup

How to set up OpenCode with cheap or free model providers like OpenRouter, Pollinations, and Copilot subscriptions to get agentic coding without the 100/month p

ai startup development
Room 3.0 Migration Guide: From KAPT to KSP, Coroutines-First APIs, and KMP Web Support
· Krystian Wiewiór

Room 3.0 Migration Guide: From KAPT to KSP, Coroutines-First APIs, and KMP Web Support

What changes in Room 3.0 for existing projects: dropping KAPT for KSP-only codegen, Kotlin-only generated code, new coroutines-first API surface, and the new we

ai startup development
· Krystian Wiewiór

Running Gemma 3 on-device: memory, quantization, and KMP

Practical engineering deep-dive into shipping on-device LLMs — comparing 4-bit vs 8-bit quantization impact on output quality and latency, managing memory press

ai startup development
Self-hosting AI models on a budget VPS: a cost analysis
· Krystian Wiewiór

Self-hosting AI models on a budget VPS: a cost analysis

Practical guide to running open-source LLMs on cheap VPS instances — hardware requirements, model selection, performance benchmarks, and cost comparison vs API

ai startup development
· Krystian Wiewiór

Ktor 3 vs Spring Boot 3: Choosing your mobile backend

Head-to-head comparison of Ktor's coroutine-native request handling versus Spring Boot's Project Loom virtual threads — covering cold start times, memory footpr

ai startup development
· Krystian Wiewiór

Zero-downtime schema migrations at scale

Step-by-step implementation of expand-contract migrations using PostgreSQL advisory locks, transactional DDL, and blue-green deployment slots — covering the exa

ai startup development
· Krystian Wiewiór

Jetpack Compose Recomposition at Scale: How Strong Skipping Mode Changes the Stability Rules You Learned

Deep dive into Compose compiler's stability inference system, how strong skipping mode (now default) changes which classes need @Stable/@Immutable annotations,

ai startup development
· Krystian Wiewiór

PostgreSQL Partial Indexes and Expression Indexes: Cutting Your Mobile Backend Query Times by 90%

Deep dive into using partial indexes for soft-deleted records, expression indexes for JSONB columns, and covering indexes (INCLUDE) to eliminate heap fetches —

ai startup development
· Krystian Wiewiór

SQLite WAL Mode and Connection Strategies for High-Throughput Mobile Apps: Beyond the Basics

Deep dive into SQLite WAL2 mode, BEGIN CONCURRENT, connection pooling patterns for Room/SQLDelight, and how to avoid SQLITE_BUSY under real concurrency — with b

ai startup development
· Krystian Wiewiór

Unit Economics That Actually Matter: Calculating True LTV When Your Mobile App Has Both Subscription and IAP Revenue Streams

Build a practical unit economics model that accounts for blended revenue streams (subscriptions + consumable IAPs), cohort-based retention curves, and refund ra

ai startup development
· Krystian Wiewiór

Event sourcing with CQRS for mobile backends

Step-by-step implementation of event sourcing for a mobile app backend, covering event store design in PostgreSQL, projection rebuilds, snapshotting strategies

ai startup development
· Krystian Wiewiór

MVI state machines: one architecture for Compose & SwiftUI

Building a production-grade MVI state machine in pure Kotlin that drives both Compose and SwiftUI views, handling side effects, state restoration, and testing w

ai startup development
· Krystian Wiewiór

PostgreSQL Connection Pooling for Mobile Backends at Scale

Deep dive into PgBouncer vs Supavisor vs built-in pool sizing, covering transaction vs session mode tradeoffs, how connection storms from mobile clients differ

ai startup development
· Krystian Wiewiór

Running LLMs On-Device in Android: GGUF Models, NNAPI, and the Real Performance Tradeoffs

A deep technical walkthrough of shipping on-device LLM inference in production Android apps — covering model quantization formats (GGUF, QLoRA), hardware accele

ai startup development
· Krystian Wiewiór

Bridging Kotlin Coroutines and Swift in KMP

Deep dive into the practical patterns for exposing Kotlin Flow and suspend functions to Swift 6 structured concurrency — covering SKIE vs manual wrappers, cance

ai startup development
· Krystian Wiewiór

I Built an AI Content Pipeline That Publishes a Blog Post in 83 Seconds

How I replaced n8n, Zapier, and paid automation tools with a custom Node.js pipeline that generates, reviews, and publishes content using Claude CLI. Real metrics from production.

ai automation development devops
· Krystian Wiewiór

Kotlin Multiplatform Room: Shared DB Without the Tax

Now that Room has official KMP support, examine the real-world migration path from platform-specific persistence (Room on Android, Core Data/GRDB on iOS) to a s

ai startup development
· Krystian Wiewiór

Contract Testing for Microservices: Stop Breaking Production

Implementing consumer-driven contract tests with Pact and Spring Cloud Contract in Kotlin backend services, covering schema evolution strategies, CI pipeline in

ai startup development
· Krystian Wiewiór

I Built Custom Claude Code Skills for Android Development — Here's How They Work

How custom slash commands for Claude Code cut my setup time from 20 minutes to 5 seconds per feature. Open source on GitHub.

android claude-code ai kotlin developer-tools open-source
· Krystian Wiewiór

Compose Multiplatform Navigation: Best Pick in 2026

A deep architectural comparison of navigation frameworks for Compose Multiplatform apps — examining type-safe argument passing, lifecycle management across iOS/

ai startup development
· Krystian Wiewiór

Eliminating ANRs at Scale: Android Responsiveness Guide

Deep dive into the architecture patterns that prevent ANRs before they happen — structured concurrency with Kotlin coroutines, main-thread budget accounting, an

ai startup development
· Krystian Wiewiór

Dependency Injection Beyond Basics: Hilt's Hidden Cost

Examining how over-reliance on DI frameworks like Hilt leads to bloated module graphs, hidden runtime failures, and testability theater — contrasting with manua

ai startup development
· Krystian Wiewiór

How Custom MCP Servers Cut AI Token Usage by 95%

Building custom MCP servers as a dev tool strategy: how indie developers can reduce AI costs and improve coding workflows by giving LLMs structured context inst

ai startup development
· Krystian Wiewiór

Kotlin Flow Patterns Every Senior Android Dev Must Know

Advanced Flow operators for production Android apps: shareIn vs stateIn, conflate vs buffer, retry with exponential backoff, and testing Flows with Turbine

ai startup development
· Krystian Wiewiór

I Hardened My VPS in One Session — Here's the Checklist

A practical, step-by-step security hardening guide for solo developers running production apps on a VPS — covering WireGuard VPN, Docker port isolation, SSH loc

ai startup development
· Krystian Wiewiór

AI Governance Architecture for Solo Devs

How indie developers and small startups can build AI governance into their products from day one — practical patterns for solo devs shipping AI features into re

ai startup development
· Krystian Wiewiór

How Much Does It Cost to Build an MVP in 2026?

A detailed breakdown of MVP development costs by platform, features, and approach. Real numbers from a developer who builds them.

mvp costs startup pricing
· Krystian Wiewiór

Why Agent Testing Is Broken (And How to Fix It)

LLM agents broke the testing contract. Here are practical, budget-friendly strategies for indie developers to test non-deterministic AI outputs without enterprise infrastructure.

ai testing llm agents software-architecture indie-dev
· Krystian Wiewiór

Case Study: Building a Cross-Platform Health App with Kotlin Multiplatform

How we built HealthyDesk — a production-ready KMP app for Android, iOS, and Desktop — with clean architecture, 20+ modules, and 80% shared code.

case-study kotlin-multiplatform mobile architecture