It's been a while since I've written for my professional techblog. I published my last update more than two months ago, and my last real blog post around four months ago. I think the reasons for this delay range from lack of direction from my sabbatical, coasting on my contract-to-hire role (coasting defined as doing my job and then doing other stuff at home), and part watching a good deal of TV (can recommend “The Office”, “Parks and Rec”, and “House M.D."). But I think the primary reason why I haven't written on my professional blog is because I failed at building TinyDev and I've been putting off admitting it (both to others and to myself). Hopefully by sharing some of the lessons here, I can move forward with developing some other side projects.
I think when I say I've failed at TinyDev, I might not be giving myself enough
credit, which is important for reasons I'll speak of later. The V1 docs are live
and have been for a few months at https://docs.tinydevcrm.com. I have a V1
docker-compose representation of TinyDev up and running locally, and that
should be reproducibly run from any environment. I've learned a ton of stuff
about devops and prod/dev deployment differences, how stretchy PostgreSQL is,
and myriad difficulties around secure authentication and realtime streaming. All
But fundamentally, I haven't shipped. Thing is, if you don't ship, you don't matter. At the very least, it's really hard to matter if you don't bring anything to the table.
Part of this failure to ship is expected. TinyDev was created as an academic project first, in order to try and stretch my knowledge by building something useful. In this respect, the project did rather well. The secondary goal of TinyDev was to ship this to production and get users. Since I committed to making this free and open-source, my long-term budget projections constrained me to keep costs to a bare minimum. It's pretty difficult to run consistent compute, storage, and memory on a free tier while expecting to scale to an unbounded number of free users.
I think I've also had to recalibrate my understanding of myself as a software engineer. For the longest time, I saw myself as this “higher-order being” who coded for edification and enlightenment and what-not. It was a pretty pretentious idea that caused me a good deal of trouble in the past, so one subliminal goal for this sabbatical is to stretch myself until I do fail. I think I mostly succeeded in this regards, and I did win myself some humility and perspective. Failing at TinyDev made me realize I do code in large part for accolades and money, and while I enjoy coding (and possibly enjoy coding enough to create a profitable side project at some point), I like making money and hearing from people more. I think this revelation buckets me a normal person, rather than an obsessive savant (no offense to those who might be). Knowing this bit about myself, whatever subjective judgements that may bring, helps me plan and develop plans for myself better.
I think there's some things I could have done differently. I failed to keep people on my TinyDev mailing list appraised of the current situation of the project, early on because I thought it would be finished rather soon, and later on because I was ashamed I was taking so long. I also failed to get something up and running in production early on because I didn't want people relying on something that I'd be willing to break willy-nilly (because it's an academic project). Lastly, it was difficult to plan too far ahead because of how any unknown unknowns
I think the idea of failing had kind of put a damper on my projects for a few months. It was difficult to get out of bed if you have a particular mindset, and changing that mindset took a while. Difficult, but necessary. I think internalizing the lesson that success isn't a straight line, regardless of how hard you try, is a healthy lesson, one to be learned sooner or later and better to be learned sooner. Now with the benefit of time and hindsight, I'll say that rather than failing at TinyDev, working on TinyDev has given me more perspective on what I need to do to ship product.
If I could take away three lessons, it'd be these:
I heavily underrated serverless as a concept. My general opposition to serverless in the past was mostly due to its cloud-native nature. I generally prefer frameworks I can reproduce locally, since I want to avoid discrepencies between local and production.
The arguments for serverless outweigh the cons though. My understanding is since serverless methods are scheduled for execution wherever there are spare resources, you can avoid paying a premium for a dedicated resource. I've been using BigQuery for some stuff lately, and it comes with a 1TB daily quota compute limit for its free tier, which is pretty crazy.
Going serverless also means you don't have to worry about scalability. It's naturally horizontally scalable. This means less configuration and coding on your end, which is time and money in your pocket.
Sometimes you shouldn't code things yourself. Not just in a no-code kind of way. For example, I learned a little bit about billing + authentication. When I came into this project, I was under the impression that token-based auth was the way to go for everything, cookie-based auth was outdated. Turns out that's not even remotely true. It's true if you want to build out a permissioning system for your APIs. But user or account management? How do you keep the token safe? How do you implement things like 2FA/MFA? Then there's billing. Apparently if you add
Stripe.jsto your client page, it takes you to an instance of Stripe's website in order to process a payment, there's nothing to do on the backend in the first place. I'd rather use Stripe than implement my own payments provider, and I'd rather use a third-party auth service rather than maintain my own auth middleware pipeline, and using both feeds into the argument of not having a complicated webapp backend at all and to use serverless instead.
After working on TinyDev, I appreciate how bundling third-party software into your application stack can make it more reliable and available.
Keep others in the loop. I thought I could write “perfect” software the first time around, if only I wrote it myself without any pre-conditions. Turns out, that's not true. If somebody can write perfect software, it's not me. So, if I'm going to be embarrassed by what I create anyways, why not share it with other people? At least then, I'll have somebody to laugh with. They can also point out where something is or isn't useful.
I took away a good deal more lessons than these, which you can read about in my TinyDev weekly updates!
I'm still interested in building some kind of a data-centric application, and relaxing some of the constraints that made development challenging (fully open-source, on-premises capable, etc). I'll post when I have anything, but I think it'll probably look like a database-backed spreadsheet application of some sort, with some number of features catered towards some niche (or scratching some personal itch).