As a small start up, your mission is to get the product off the ground quickly. You must strike a balance between cutting the right corners, and creating an infrastructure that scales.
We know, because we built RemoteHQ from the ground up with a technical staff of one (yours truly).
Here are 5 elements you must get in place before ramping up your development team:
- A programming language
- Cloud-provider services
- Your deployment pipeline
1. Choose a programming language that speaks to you
When selecting a programming language, focus on your product requirements. If there’s a toss up between languages, look to your core business values to inform your decision.
At RemoteHQ, we chose Go, based on the following criteria:
- Type checking
Statically typed languages catch defects at compile time. You’ll spend less time debugging and have a higher level of confidence while you build up your unit tests.
- Error handling
Although it yields verbose code, languages that return (or gracefully handle) errors reduce vulnerabilities and force developers to explicitly handle each use case.
- Learning curve
We needed a quick and painless onboarding process. Go is easy to read and learn, relative to other statically typed languages, and has a robust standard library.
- Deployment confidence
Running our CI/CD process, from staging to production, could not introduce or remove (think left pad) key external dependencies. Go compiles to a statically linked binary that you can run in any environment with the same target OS/CPU values.
2. Get the most out of your cloud provider
Focus on building your product, not managing infrastructure services. To hit the ground running, you’ll need a cloud provider that gives you the most bang for your buck.
At RemoteHQ, we chose Amazon Web Services and Google Cloud Platform. Here are some of the features that saved us a significant amount of development time:
- Object storage
- In-memory datastores, such as Redis
- Database configuration, including read replicas
- Container orchestration frameworks (Elastic Kubernetes Service, Google Kubernetes Engine)
3. Invest in your deployment pipeline
To iterate quickly, and ship new features as soon as possible, invest in your deployment pipeline up front. Your team needs high confidence that their code deliveries do not introduce unwanted bugs or behavior in production.
Here’s an overview of the steps in our deployment pipeline:
- Static analysis and linting
- Run unit tests
- Build binaries, images and tags
- Deploy to staging environments
- Run smoke tests
a. If smoke tests pass, push to production
b. If smoke tests fail, roll back
4. Practice observability
Bugs in your product are expected. The trick is whether you have the tools to identify and resolve them as quickly as possible.
Here are a few ways to improve the observability of your product:
- Follow best practices for structured logging
- Export logs to an external system
- Implement request IDs, so you can trace calls within a single system
- Create alarms based on your log data, by using third-party tools such as CloudWatch
5. Stay nimble (build for change)
Believe in the longevity of your product. Just because your runway to launch is short, doesn’t mean you need to make short-sighted decisions.
To ensure that you can extract logical units from your product to deployed services in the future, separate roles, responsibilities, data, and ownership at the code level.
Here are a few ways to follow domain driven design:
- Define logical boundaries at the lowest level, by putting data models in their own database schema.
For example, separate information about: users, billing, and authorization.
- In your code service layer, define clear APIs that own their models, schema, and tables.
Even though all interactions start off as in-memory calls, you can easily convert your APIs to Remote Procedure Calls in the future.
- Implement an event-driven architecture that’s synchronous.
Send events by using REST or Direct Method Invocation from your service-level APIs.
You’ll avoid the cost of implementing an event bus, such as Kafka, RabbitMQ or Amazon SQS, but still be able to support asynchronous events via Pub/Sub in the future.
I’ve worked at software companies of all sizes and stages of growth. The common challenges and pitfalls, horror stories, and lessons learned from those experiences helped guide me through the early days of development.
Today, I’m happy to report that RemoteHQ has minimal technical debt, and continues to keep pace with its growing user base. Our engineers onboard quickly and start contributing immediately. Because we adopted best practices early on, we can support traffic spikes and growth spurts (like the ones caused by COVID-19), without overhauling our architecture and design.
Early-stage development can be daunting. Take the time to make thoughtful choices, weigh tradeoffs, and invest in your infrastructure.
Good luck on getting your project off the ground!
Louis Sivillo is the CTO and co-founder of RemoteHQ. He is a software engineer with more than 15 years of experience in DevOps, programming, and software architecture.