Joshua Paling

Joshua Paling Joshua Paling http://blog.url.com/ 2021-05-26T00:00:00Z Joshua Paling Every New Hire Must Raise the Bar http://blog.url.com/blog/2021/05/26/some-management-lessons.html 2021-05-26T00:00:00Z 2021-06-21T11:58:31+10:00 Article Author <p>Just a few personal lessons here, recording for my own reference.</p> <h2 id="set-an-extremely-high-bar-on-hiring">Set an extremely high bar on hiring</h2> <p>Hiring is the most important thing you do as a manager. And every new hire must raise the bar. They must make the whole team better. This is an <a href="https://www.aboutamazon.com/news/workplace/hire-power-how-amazonians-raise-the-bar-with-every-interview">Amazon principle</a>, but it's universally applicable.</p> <p>If you're unsure, pass on the candidate, or add an extra interview step to provide more certainty. Hire only when you're very confident that this candidate will be a bar-raiser.</p> <p>When a good hire joins, it raises morale and productivity across the whole team. Likewise, a bad hire is a wet blanket on the whole team.</p> <h2 id="own-your-bad-hiring-decisions">Own your bad hiring decisions</h2> <p>You'll make some. Hopefully not many, if your bar is high enough. But when you do, own it. They must be given direct, specific feedback, very quickly. If they can't turn around quickly, you must let them go within their probation period. The question to ask, regularly throughout the probation, is "if I could just re-wind time, would I hire them again?" If the answer's no, they can't pass probation.</p> <p>Letting someone go sux for everyone - you, your team, and most of all, the person being fired. If you're doing it more than "very rarely", it means your hiring bar isn't high enough. You still must do it! But raise your bar to prevent it in future.</p> <h2 id="create-a-strong-feedback-culture">Create a strong feedback culture</h2> <p>Not just for new hires, but for everyone. If a manager has negative feedback for a report, it must be delivered quickly. Don't wait for next performance review. And usually, don't wait for next 1:1. The feedback must be direct, specific, empathetic, and framed in the best way to allow the report to quickly change and grow.</p> <p>You must lead by example on delivering feedback to this standard; culture filters down from the top. It's scary at first, but most people - either immediately, or at least later upon reflection - appreciate the honesty and opportunity to improve.</p> <p>Likewise, positive feedback is easy to forget about (if everything's going well, no need for feedback, right?). But it's equally important. Positive feedback must be specific and heartfelt. "You're doing a great job" isn't good enough - what exact thing are they doing well, and what good outcome is it creating? Why do you truly appreciate them doing it? Let them know - and usually, do it in a public channel so they know the team is aware of their effort, and so the team knows what "doing a great job" looks like to you.</p> Hiring Offshore http://blog.url.com/blog/2021/05/26/hiring-offshore.html 2021-05-26T00:00:00Z 2021-05-26T20:25:35+10:00 Article Author <p>Though most of our engineers are based in Australia, at work we've now got teams in Ukraine, Sri Lanka, India, and Brazil. Here's some tips.</p> <h2 id="dont-lower-your-bar">Don't lower your bar</h2> <p>If you wouldn't hire them for full price at on-shore rates, don't hire them off-shore just because they're cheaper. Sub-par developers are a drain on the entire team, and not worth having at any cost. Be willing to pay a bit extra to get the best developers overseas, just like you would, here.</p> <p>We're using an agency, so applicants come to us already pre-vetted. Still, we interview them again and turn down a majority. Finding pre-vetted candidates, then vetting again yourself, is the right approach.</p> <h2 id="communication-is-as-important-as-technical-ability">Communication is as important as technical ability</h2> <p>You absolutely must be able to communicate easily, both in writing and over the phone. No amount of programming expertise changes this. This means that your off-shore hires must be great at English, or they must be managed by an on-shore team member who speaks their language fluently.</p> <h2 id="over-do-communication-early-on">Over-do communication early on</h2> <p>Anecdotally, I've noticed off-shore developers being reluctant to ask for help, and reluctant to take help even when it's offered. Insist on pair-programming with new off-shore starters for at least a couple of hours a day, every day, by default as they start off. Let go gradually as it's clear they have a firm grip of the wheel. Emphasise how useful it was, and encourage them to reach out for help whenever needed. Even if they're not reaching out for help, pro-actively reach out</p> <h2 id="encourage-autonomy-and-push-back">Encourage autonomy and push-back</h2> <p>Off-shore hires tend to do whatever they're asked, with little or no push back. But you don't want that! Emphasise that you might be wrong, that they can question or challenge your advice. Praise it when they do. It's a waste of their intelligence to be merely a pencil in your hand.</p> <h2 id="be-patient">Be patient</h2> <p>If you're not finding great hires, keep looking. Among the billion people in India, there's exactly zero chance that there's not thousands and thousands of great programmers. Yes, we've all heard the bad stories. Those people didn't have their hiring bar high enough.</p> <h2 id="treat-them-as-first-class-citizens-of-the-team">Treat them as first class citizens of the team</h2> <p>Because they're cheaper, because they're not permanent / direct employees, and because they <em>feel</em> further removed, it's tempting to give off-shore hires second-class service as a manager. "I know they're blocked… but I'm busy, I'll get to it in a few hours" or "Doesn't matter if it takes twice as long; they're half the cost anyway".</p> <p>Don't. Apart from being a shitty thing to do, there's a big opportunity cost in leaving good developers un-supported. As much as reasonable, give your off-shore teams the same level of support and service as your on-shore teams.</p> Breaking Prod http://blog.url.com/blog/2018/07/27/breaking-prod.html 2018-07-27T00:00:00Z 2021-06-21T11:51:56+10:00 Article Author <p>When broken production apps break, stakeholders immediately ask: <em>“What can we do to ensure this never happens again?”</em></p> <p>The relationship between development speed and bugs looks something like this:</p> <p><img src="../../../../images/bugs-vs-speed-f15f9700.jpg" alt="Bugs vs speed" /></p> <p>Rushed pace &amp; poor testing means many bugs. Slow down (ie, be more thorough), and at first you’ll drastically reduce bugs. But slow down more, and you begin to bottom out. You can never reach zero.</p> <p>Breaking prod less means using time, money, and bureaucracy to slide right on an axis of diminishing returns.</p> <p>Finding the sweet spot requires ongoing collaboration between business and tech. Since sliding RIGHT is expensive, you want to be as far LEFT as your appetite for risk allows.</p> <p>Writing pacemaker firmware? Slide very far right to ensure no one dies.</p> <p>Selling shoes online? You have a higher tolerance for risk. Slide left and <em>take advantage of it.</em></p> <p>Coming back to the original question, the answer is <em>“we can slide as far right as you want, but it’s not free… how much do you want to pay for it?”</em></p> <hr /> <p><em>Update:</em> What <em>is</em> important is to look for opportunities to efficiently decrease the risk of bugs. People's knee-jerk reaction to "prod is broken!" is to ramp up bureacracy with generic solutions like:</p> <ul> <li>Ensure every PR has 2 reviews, not 1!</li> <li>Do a second round of testing before promoting to prod!</li> <li>etc</li> </ul> <p>These make you feel like you've "done something about it" but you haven't. They slow the team down and don't really reduce risk. Instead, look for specific, low bureaucracy process changes that target high risk scenarios. Example:</p> <ul> <li>If someone posts in the #support slack channel after business hours, auto-respond with instructions on how to alert the on-call staff.</li> <li>When releasing a significant feature outside of business hours, document a rollback plan and communicate it with on-call staff</li> </ul> Data imports done right http://blog.url.com/blog/2016/12/22/data-imports-done-right.html 2016-12-22T00:00:00Z 2021-05-26T19:06:31+10:00 Article Author <p>I’ve been bitten more than once by data imports consuming an unreasonable amount of time in software projects. Here are some lessons.</p> <h2 id="know-what-to-expect">Know what to expect</h2> <p>The client (or whoever is sourcing the data) will give you poor quality data from disparate sources, and they’ll drip-feed it over a period of way-too-long. Each version will be in a slightly different format. They’ll say “just get started with this” then want a complete re-do with fresh data later. They’ll give you the final copy, then the actual final copy, then the final FINAL copy. Eventually, you’ll get the real actual final renamed FINAL CONFIRMED copy. A few months after going live, they’ll want to import a bit more data that they forgot about the first time round. Expect this.</p> <p>You will end up running your import scripts countless times, with dozens of variations in the data format supplied by the client.</p> <h2 id="know-how-to-deal-with-it">Know how to deal with it</h2> <h3 id="your-import-scripts-should-be-production-level-code">Your import scripts should be production level code</h3> <p>You and your team will run them enough to make this MORE than worth it. Write unit tests. Have tests for each edge case. Name them well. Where there’s cheap performance wins, take them. Commit them to the codebase with the expectation that they’ll live there for several months, minimum, and be used countless times.</p> <h3 id="your-import-scripts-should-be-easily-re-runnable">Your import scripts should be easily re-runnable</h3> <p>You should be able to re-run them with a single command — ./import.sh or whatever. You should not have to manually delete or otherwise wrangle around with data in the database, or csv files, or anything else, before re-running.</p> <p>Your import scripts should take care of either: deleting all data before they re-run, or running in an idempotent kinda way so on the second run through, they’ll update the same existing record if it exists, rather than adding a duplicate.</p> <h2 id="your-app-primarily-your-database-schema-should-dictate-the-data-format-for-imports">Your app (primarily your database schema) should dictate the data format for imports</h2> <p>When the client gives you a messy spreadsheet, it’s easy to think: “That’s Ok, I’ll write script that loops over this, untangles it, and imports it directly to the database”.</p> <p>Don’t do this. Don’t let the mess of spreadsheets you’re provided with dictate the data formats used by your import scripts. Imagine if the app was in production and the client wanted a page where they could upload a CSV of additional data at any time, and expect to get understandable errors when data didn’t match the expected format. You’d have to dictate the format of the CSV. What would you ideally dictate? That’s the format your inport scripts should use.</p> <p>This requires a little more thought and effort up front on your part, but it pays back in the long run.</p> <p>If you have to deal with a dirty spreadsheet of data, the approach should be to write a (possibly dirty, throw-away) script to transform that data into the format your app expects (ie, a format closely matching your app’s database schema), then import the transformed data using your nice, production quality code.</p> <p>Alternatively, don’t write script to transform messy data, and just tell the client: “This data isn’t in a suitable format. Here’s a template CSV with the headers we expect. Fill that out and send it back”.</p> <h3 id="you-mostly-want-one-import-per-table-as-the-database-schema-changes-modify-existing-scripts-dont-add-new-ones">You mostly want one import per table. As the database schema changes, modify existing scripts; don’t add new ones.</h3> <p>Let’s say a client wants to give you data about restaurants. They have the restaurant names now — but will give you the addresses later. So, create a restaurants import script that handles just names now. Later, modify that same script to handle both names and addresses. Don’t create a second restaurant_addresses import script later. One script per table, modify it as the schema for that table changes.</p> <p>Ideally, when the client says “I have the addresses data now”, you say “great — add it to this spreadsheet which already contains the names, and empty columns for the address data, then send that spreadsheet back to me”. Of course, since your expected CSV format closely matches your database schema, it’ll be easy to export a CSV of existing data using your favourite RDBMS client.</p> <h3 id="know-whos-responsible-for-providing-clean-data">Know who’s responsible for providing clean data</h3> <p>In almost all cases, the ultimate responsibility of providing clean data (or cleaning up bad data) should lie with the client. That should be clear in writing prior to starting the job.</p> <p>Ideally, the job of getting that clean data into the most convenient format for your app should also lie with the client — that is, you should be able to say “here’s how the app’s import scripts expect the data to look”, and they’ll provide you data looking like that.</p> <p>Both the above steps (getting clean data, and formatting it) ALWAYS take WAY longer than expected. So avoid those responsibilities if you can.</p> <p>Of course, in practice, you’ll cut the client some slack and sometimes tidy up data for them. But having it clear in writing that cleaning and formatting data is their responsibility means after the 20th iteration of being provided unsuitable data, you can say “Stop! Get us clean data, and then we’ll continue. Or, pay us extra for cleaning up dirty data, because that work is outside scope.”</p> <h3 id="dont-be-too-preoccupied-with-getting-real-data-in-your-app-early-on">Don’t be too preoccupied with getting “real” data in your app early on</h3> <p>It’s tempting to jump the gun and get “real” data in your app to make your dev or staging environment feel more complete or realistic, even when the data you’ve been provided so far is a messy, inconsistent or incomplete. Avoid this temptation.</p> <p>The danger here is that every time you find a bug in the app, you’re never sure wether it’s a result of bad code, or bad data. Sticking to a smaller subset of “non-real” but clean, correct, consistent data ensures that when you do have a bug, you can be a lot more confident that the codebase, not the database, is where you should be trying to fix it.</p> <p>Always make every effort to avoid having any inconsistent / incomplete data, even in the early stages of development / prototyping.</p> <p>Maintain a small but complete and consistent subset of data that you can use for development, until ALL of the real data becomes available.</p> <h2 id="overestimate">Overestimate</h2> <p>Often the advice for estimating software projects is “decide how long you think it’ll take, then double it”. For data imports, multiplying by 4, or negotiating to do that part of the project hourly rather than fixed cost, is a safer bet.</p> How to make fixed price work http://blog.url.com/blog/2016/10/14/how-to-make-fixed-price-work.html 2016-10-14T00:00:00Z 2021-05-26T19:22:31+10:00 Article Author <p>Customers want fixed price. Here’s how to make it a fair deal for yourself. I recently read <a href="https://twitter.com/arohner/status/766688027745751041">this tweet-storm</a>, on why you should never take fixed price contracts.</p> <p>It says:</p> <blockquote> <p>Unless you’ve done the job 20 times, and can estimate how long it will take with a high-degree of certainty, fixed-price is suboptimal. Like the over-under in betting, someone wins, and someone loses. And to answer who is more likely to win, the contractor or the employer, you can answer with another question: When was the last time you had a software project come in on-schedule? For clarity, fixed duration contracts are fine: “You pay for N weeks of work, I do N weeks of work”. Where you get into trouble is: “I pay for N weeks of work, regardless of how much time it takes to complete”. The employers who do this tend to also like to play games with what is in vs. out of scope. Avoid.</p> </blockquote> <p>Having spent years in a small digital agency where &gt; 95% of our work was fixed price, I agree with all the points. The problem is, almost all customers want a fixed price.</p> <p>Here’s some tips for making fixed price work.</p> <h2 id="fixed-price-is-insurance">Fixed price is insurance</h2> <p>This is the golden rule. In a fixed price job, you’re selling the customer two things:</p> <ol> <li>The product you’re building them</li> <li>Insurance on the cost of that product</li> </ol> <p><strong>Insurance costs money.</strong> In the case of software, you should charge \~30% additional for fixed price jobs. You can tell the client this in plain english. They will still want fixed cost for the same reasons they still buy travel/car/indemnity insurance.</p> <p>Companies selling insurance (ie, you):</p> <ol> <li>Don’t win on every single customer. They win overall.</li> <li>Have different premiums for different customers, based on risk.</li> <li>Have strict written terms on what is and isn’t inside the scope of the insurance policy.</li> </ol> <h2 id="estimating">Estimating</h2> <p>You’ll drastically underestimate your first few projects. Don’t underestimate the next few. Here’s some tips:</p> <ol> <li>Hofstadtler’s law states “It always takes longer than you expect, even when you take into account Hofstadter’s Law.” This is doubly true of software.</li> <li>Break the work into small chunks, estimate each, then total.<br /> You’ll want to break the project into chunks for writing your scope too. More on that later.</li> <li>Scope will change. The client doesn’t know what they want yet. You’ll write a formal scope to protect you against scope change, but asking for more money at every tiny change sucks. Allow a significant amount of fat so you can absorb some reasonable amount of scope change.</li> <li>Consider the value of the job to the client. Is it a game changer for them? If so, charge more.</li> <li>Got your estimate? Now, Double it. Everything takes twice as long as you think.<br /> <em>And DON’T consider the fact that it’ll get doubled when going through the points above!</em></li> </ol> <h2 id="wont-i-be-out-competed-on-price">Won’t I be out-competed on price?</h2> <p>Companies who get a few quotes on a job will get figures all over the place. Not everyone’s shopping for the cheapest price, and regardless of your price point, you’ll have people turning you down for being too expensive, and others turning you down for being too cheap. Yes, really.</p> <p><em>You want to go for the clients who know cheapest isn’t best.</em> Not only do they pay more, they’re also usually more professional, less petty, and much more enjoyable to work with.</p> <h2 id="writing-a-scope">Writing a scope</h2> <p>For a significant sized job, you should write a scope and have clients read and sign it before commencing work. Most clients won’t actually read it, but do it anyway.</p> <p>A scope should detail what you will complete under the fixed cost. It should also outline what you won’t complete. You can place this under a euphemism like “Future Considerations”, and mention that these are ideas / possible enhancements for future, not included under the current scope.</p> <p>A scope is what you’ll fall back on when your client says “… but I wanted this from the beginning” and you say “it wasn’t mentioned in the scope — we can do it, but at additional cost”. Assuming you’re being fair and telling the truth, clients will usually accept that without much fuss.</p> <p>A scope is also what you’ll fall back on, on the off chance things get much worse than that. A scope is like writing the terms for the insurance you’re offering. Insurance companies don’t say “sure, we’ll cover any unexpected expenses you have on your holiday, no questions asked!”</p> <h2 id="payment">Payment</h2> <p>It’s hard, but if you can, charge some amount to prepare a scope. One way to pitch it is “it comes of the cost of the job if you go ahead with us”. Companies can, and will, get you to write a great scope, then take your scope out to tender with cheaper companies that would not have done half as good a job of scoping out their project. A good scope is worth money in its own right.</p> <p>Take a deposit up front. For smaller jobs (say up to 20k), take 50% up front, as soon as the scope is signed. For larger jobs, break it into milestones as makes sense, but the first payment should be up front, before starting work.</p> <p>The last payment should be prior to going live — as in “it’s in staging and we’re ready to flick the go live switch once you pay”. Even if you trust the client, invoices get paid much more slowly after the project is live! (If the client resists, you may hold back some nominal amount to bill after it’s gone live, but 90% + should be before.) Most importantly, watch Mike Montiero’s great talk <a href="https://www.youtube.com/watch?v=jVkLVRt6c1U">“Fuck you, pay me”</a>. I can’t say I follow all his advice, but I probably should.</p> <h2 id="no-claim-bonus">No claim bonus</h2> <p>You know how insurance companies have a “no claim bonus”? That’s clever marketing. It means “clients who make claims get charged more”. You can do the same. For difficult clients, or clients where you’ve lost out before, charge them a higher premium for future fixed price work (and recoup some of what you lost previously).</p> <h2 id="tracking-time--estimates-vs-actuals">Tracking time — estimates vs actuals</h2> <p>Fixed price means you’re under no obligation to track time. It’s a good idea to do so anyway, for your own future reference. Don’t be too transparent with the client, though.</p> <p>If you do fixed price right, there’ll be plenty of times where you come in under estimate, and the client could have got it cheaper at an hourly rate. That’s completely fair — fixed price is insurance, which the client wanted. You took the risk and it paid off. But there’s nothing to be gained from letting the client know that this time, you won.</p> <p>Many clients expect a “Fixed price if it goes over estimate, but hourly if it goes under” deal — and that’s simply not viable for you. Fixed price means actual hours aren’t the client’s concern.</p> Questions for potential employers http://blog.url.com/blog/2016/08/08/questions-for-potential-employers.html 2016-08-08T00:00:00Z 2021-05-26T17:57:47+10:00 Article Author <p>Unexpected circumstances have meant I've done two job hunts in recent months. I usually scribble down a handful of questions to ask or consider prior to each interview. Here they are so I can remember and refine them over time.</p> <ol> <li> <p>What does the business do? Who's the target market? What's the dream? How big to you want to get etc?</p> </li> <li> <p>How long have you been around? Are you profitable? Have you taken VC? Who are the main people strategically driving the direction of the business?</p> </li> <li> <p>How big's the dev team? How many people? What roles? Full timers, part timers, contractors? How long have the core members been there? Who would I be reporting to and working with most closely?</p> </li> <li> <p>How's the leadership structured, and how's work delegated? Top down? Flat? Collaborative? Do you follow any specific development methodologies?</p> </li> <li> <p>What tech stack are you using? (and subsequently… you mentioned X an Y, which I don't have experience with. Are you OK with that?) <em>They should at least be fine with you not knowing peripheral technologies in their stack.</em></p> </li> <li> <p>Are you open to remote work? Does anyone actually work remotely? If so, how often? Have you found it good / bad / indifferent? What are typical work hours? Are you flexible with the times people work? Do people take advantage of that flexibility?<br /> <em>Being "open to remote work" and having people who actually do it are two different things. Likewise for flexible work times.</em></p> </li> <li> <p>What will I learn from a technical standpoint in this role?</p> </li> <li> <p>What are the career growth opportunities - both within this role / company, and if I were to move on in a year or two's time?</p> </li> <li> <p>How do you manage technical debt and maintain code quality?<br /> <em>There are lots of valid answers to this. A vague answer is a red flag.</em></p> </li> <li> <p>Do you pay for employees to go to Ruby Conf and Rails Camp (or other equivalents)? Do you do anything else regarding ongoing professional development for your employees? A "yes" here is good and reveals a lot about general attitude towards employees.</p> </li> <li> <p>What are your expectations regarding pay?<br /> <em>I used to be very uncomfortable talking about pay. One of the best life skills you can get is the ability to talk about it in a confident, upfront, open manner.</em></p> </li> </ol> <p>Edits: additional questions / comments given to me on twitter:</p> <p><a href="https://twitter.com/sevenseacat/status/769855544349773825">Rebecca</a>: "some of those would be useful to ask to both the employer, and one of the devs you would be working with. Compare the answers."</p> <p><a href="https://twitter.com/pat/status/769860587677331457">Pat</a>: I'd be asking questions about culture and diversity - is it on the company's radar? How are they addressing such things? <br /> <a href="https://twitter.com/pat/status/769864749735550976">and</a>: I'd also be keen to hear about leadership (top-down, collaborative, etc) and ownership (profit-sharing? equity?)</p> <p><a href="https://twitter.com/RudyYazdi/status/769862693205311488">Rudy</a>: I'd throw in something along the line of: "how do you measure my performance?" type question too ;)</p> <p><a href="https://twitter.com/grokfail/status/769907753758228480">Garrow</a>: how do you decide what gets built? Who does that? How do you measure the success of built thing?</p> <p><a href="https://twitter.com/andrewdotnich/status/770197793424105473">Andrew</a>: do you have any references? (I have to provide them, so where are yours?)</p>