The Journey
My professional journey at Fokvs (sole work experience), covering the rebuild, migrations, monetization, and team process setup.
When I joined as CTO in May 2023, I inherited a complex infrastructure that didn't match the scale or needs of the business:
- 7 microservices in Python running on AWS Lambda
- A separate API in Java
- 3 different databases: Neo4j, MySQL, and DynamoDB
- Flutter app and React web platform
- R$600/month AWS costs for a handful of users with no monetization
There was no logical reasoning behind these choices—it was built incrementally based on what was known at the time, without considering scalability or cost efficiency.
My first major decision as CTO was to simplify the infrastructure. With no monetization and low usage, the complex setup wasn't justified. I proposed and executed:
- Single unified API in NestJS, built from scratch
- PostgreSQL as the single source of truth
- Rewrote the web platform in Next.js for better SEO
- Hosted entirely on Fly.io for managed, affordable infrastructure
I wrote all the code for the new API and handled the migration. This foundation enabled rapid product iteration and set us up for growth.
As the product scaled and usage grew, we needed more control and scalability than the managed platform could provide. I orchestrated a complete migration back to AWS:
- ECS Fargate deployment: Dockerized containers with autoscaling capabilities for handling traffic spikes
- Production-grade infrastructure: RDS Postgres, ElastiCache Redis, CloudFront CDN, private subnets with bastion hosts
- 100% Infrastructure as Code: Entire infrastructure managed with Terraform for reproducibility and version control
- Zero-downtime migration: Carefully planned and executed migration with no service interruption, maintaining 100% uptime during the transition
- Scalability and control: Infrastructure designed to support 100K+ users with full control over scaling, monitoring, and cost management
This migration provided the foundation needed to scale efficiently while maintaining cost control and operational excellence.
Finding sustainable monetization was challenging. Most materials were old exams, creating copyright concerns. We tried multiple approaches:
- B2B partnerships: Banner ads and job board integrations. Revenue grew from R$200 to R$650/month, but required manual, labor-intensive distribution through university groups.
- B2C credit sales: Users could buy credits to access materials. Some sales, but not scalable.
- First subscription model: Unlimited access subscription. Only 3 subscribers—didn't scale.
- AI Question Scan + new subscription: This was the breakthrough. Launched alongside the new subscription model, it drove consistent subscriber growth.
Through user interactions, we discovered that the main incentive for sharing materials was the pure instinct to help classmates—almost like a status symbol. The ambassador program leveraged this natural behavior:
- Personal onboarding: Initially, we did calls with every applicant to understand our target audience better
- Compensation model: Rewarded in money for material uploads (milestones) and views. Ambassadors had a dashboard with balance that could be withdrawn once minimum threshold reached
- National expansion: When videos went viral, ambassadors came from all over Brazil. We grew in top federal universities, exactly our target. Currently: 600 active ambassadors, 4K waitlist
- Technical challenge: Built event-driven system with transactional ledger. Later refactored to support two concurrent program versions during migration, slowly migrating users between versions
As the product grew, I took on the responsibility of scaling the product team and establishing clear processes:
- Hiring and onboarding: Recruited and onboarded new product team members, creating comprehensive onboarding materials and processes
- Development process documentation: Established clear development workflows, from planning to deployment, with practical examples and checklists
- Internal handbook: Created a living documentation system covering processes, PRD templates, quality principles, and tool usage guidelines
- Quality standards: Defined coding standards, testing requirements, and review processes to ensure consistency across the team
- Mentoring and knowledge sharing: Conducted regular knowledge transfer sessions and mentored team members on technical best practices and architecture decisions
These processes enabled the team to scale effectively while maintaining high quality standards and alignment on technical direction.
We created the checkout system specifically to enable a direct sales model for subscriptions. This approach fundamentally changed how we acquired and converted users:
- Meta ads campaigns: Multiple campaigns driving traffic to various landing pages across different platforms
- Distributed landing pages: Landing pages scattered across Framer and Lovable, each redirecting to the unified checkout system
- Complete attribution tracking: All variants tracked end-to-end, enabling precise measurement of campaign performance and conversion rates
- Simplified sales funnel: Users buy before using, making attribution trivial and revenue scaling predictable
- Predictable revenue scaling: The simplified funnel and clear attribution enabled data-driven optimization and reliable revenue growth
This direct sales model transformed our acquisition strategy, making it easier to measure ROI, optimize campaigns, and scale revenue predictably.
Early Technical Decisions
- PDF thumbnails: Initially stored binary thumbnails in Postgres columns using GraphicsMagick. Worked well initially, but as materials grew, migrated to S3 with URL fields. Maintained API compatibility by redirecting to S3 URLs
- Reactions system: Started with simple like/dislike in a reactions table with COUNT queries. As Instagram had, this became slow. Denormalized with like_count fields updated via triggers. Later evolved to 1-5 star rating system
Architecture Debt & Improvements
- Growing complexity: As features expanded, services became large, tightly coupled. Business logic was mixed with infrastructure. KnexJS queries became massive, making business logic testing nearly impossible
- Developer experience improvements: Improved rebuild times, hot reload, environment replicability. Created seed system from anonymized production data, downloaded sample static materials and alternated between them in Minio to save space—no S3 dependency for dev
- Future refactoring: Backend still needs major refactoring. Ideal would be closer to DDD architecture to properly separate concerns
