Okay, look, I don’t know how to kick this one off. This could’ve been titled One Weird Trick The Secret Cabal Of Productive Engineers Doesn’t Want You To Know About. Could’ve been, because it’s true (kinda - I haven’t checked in with the cabal in a while), but it also is a lame title.
Another possible title: The One Thing (I Think) That Might Be One Of The Most Important Things A Developer Can Do. That one stumbles right off the tongue and crashes the landing. Another one: One Crucial Skill Every Developer Should Master. Also bad.
The problem: what I want to talk to you about sounds so, oh so boring (except if you like bulleted lists), but I truly think it’s important and one of the fundamental skills a lot of effective engineers have.
I’m talking about making a plan. A plan for something you want to implement. I’ve also heard this being called a technical plan, or a technical concept, or a breakdown, or- well, most often it’s called a plan.
It’s something I’ve been asked to do ever since I started programming professionally and by now I subconsciously do it every time I need to think about how to do something, answer how long it would probably take, whether it has parallelizable parts, after which point I could ship, when it’s possible to pause, and so on.
Say the task is this: allow users to upload avatars on their profile page and display those avatars.
A plan that I’d write in the ticket (or in my notes), would look roughly like this if I were using a framework like Rails:
Goal: allow users to upload avatars on their profile page and display those
avatars
Tasks:
- migration to add `avatar_url` to `users` table, default null
- change `User` model definition to also include `avatar_url`
- add AWS S3 bucket configuration to app, including test/staging env
- create bucket (bucket name? permissions? ask product/infra)
- add AWS library so we can do URL signing
- change profile edit page to render pre-signed upload URL to POST uploads
directly to S3
- use library in controller to create pre-signed URL
- add route to accept avatar_url
- add `UserAvatars` controller with `create` action that accepts `avatar_url`,
which is S3 URL
- frontend: add upload form on profile page that will post uploaded image to
pre-signed POST url directly to S3
- profile page: render `<img>` if `user.avatar_url` is not null
- frontend: CORS???
Open questions:
- bucket permissions?
- what do we do when user uploads avatar and they already have one? do we delete
old one on S3 on successful upload?
There’s probably something missing or something wrong with this. Sorry, but I just typed this out while imagining a hypothetical Rails app and I haven’t worked with Rails in 5 years.
You get the idea though. It’s a rough plan on how I’d implement this feature, from database migration up to frontend changes, in various degree of detail.
Is it incomplete? Yes. Will this plan change? Yes, likely, see the open questions at the end – those are things that popped into my head while writing, indicating that not everything about this feature request is crystal clear.
Is it still worth writing? One hundred thousand million percent. Absolutely. Because here’s the thing: it’s not only about the plan itself, it’s about the thinking we did to get to the plan.
The tasks above I didn’t have to write down. I could’ve just started programming. But then on the 2nd day, after I stumble out of the S3 AWS library docs with scratches in my faces, I’d realize: hey, what do we do with already uploaded avatars? Do we delete them? How? Do we have enough information on the backend to do that? Or do we need to store more information? Do we need to store bucket and filename in the database too?
The plan is not only useful because it gives you something you can check off while you do your work, or something that you can split and delegate (hey, what about those “frontend” parts – can someone else do that?), it’s useful because by writing it out you are actively thinking about what you’re supposed to be doing. Meaning: it helps you do it better.
Writing the plan helps you construct a mental model of all the work required. You’ll see whether you need database changes, only frontend stuff, whether this takes 1 week or 1 month. The amount of times I have written down a plan like this and suddenly sat up straight saying “wait, this is not that easy”? Many, many times.
Don’t get hung up on the form of the plan here. Not every plan looks like the one above. They could be higher-level and contain less details, or they could be even more detailed. They could be longer and contain not only the avatar-upload feature, but the whole user profile page and its sub-features. Sometimes I don’t even write it out.
What’s important is that you have a plan so that when someone asks you whether you know what you do, you do.
And yet I see so many engineers not ever creating plans or struggling when attempting to do so. Why? I’m not sure. I can only guess. Maybe it’s because it’s often easy to simply start, because there’s usually something that everybody agrees on (in the case above: everybody would agree that we have to store a URL of an avatar somewhere), and having to think through the rest seems like a waste of time? Maybe it’s because people struggle with the mental model behind the plan - they can’t think through how all of the parts interact because they can’t “see” that far? Not sure.
The good news: making plans helps you get better at making plans. Just start doing it. Next time you have to implement something, open a todo.md
file and write down those tasks. Read through the list again and add things you missed on the first pass. Do this until there’s no more changes when you do a pass. Then hand that list to your colleague and ask them: does this look right to you? Maybe they can help you and point out something you missed. Then look at your list and ask yourself: how long will it take to do all of this? 3 days? 4? Maybe 5. But notice: it’s not wild guessing anymore, you now know roughly how much work it is - roughly. That’s already a lot better than saying “I don’t know”. Then look at your list and order things the way you’d implement them. If you need to split up your work with a colleague, add names next to each task.
Then take a step back and pat yourself on the shoulder. Congratulations, you now have a plan.
I liked it.
As Eisenhower famously said - plans are nothing, planning is everything.