Skip to content


Convert Average Annual Return (AAR) to Compound Return (CAGR)

One of the confusing things around private investments — especially real estate syndicators — is advertising “Average Annual Returns” (AAR). I personally find this a bit shady because they can’t be directly compared to other returns such as the stock market, which are compound returns (specifically, using Compound Annual Growth Rate or CAGR). For example, you may see a real estate syndication with a target 14% AAR. Whoa! you think. That’s so much better than stocks. But wait – you’re comparing apples and oranges.

Of course, sponsors are “stuck” using AAR because if they advertise using CAGRs now, their returns will look inferior to their competitors. So this is an industry problem.

Concretely, if you invest $100k for 5 years with an Average Annual Return of 14% that means that you’ll have $170k in 5 years. (100,000 * (1+0.14*5)). But if this were a CAGR of 14% instead of just an AAR, after 5 years that same $100k would have been worth 100,000 * (1 + 0.14)^(5 years) = $192.5k. Oof, you would have received $22.5k less than you expected from the advertised 14% return! That’s why you need to convert this Avg Annual Return to a CAGR for relative comparison.

To do this conversion, we have to start by defining each term:

  • AAR is the total return divided by the number of years it took to achieve. In the above example, you gained $70k on top of your original $100k investment in 5 years. That’s (70,000 / 100,000) / 5 = 14%.
  • CAGR accounts for compounding by applying this rate each year. You invest $100k, after 1 year at 14% return, you have 100k * (1 + 0.14) = $114k. In year 2, this $114k grows another 14%: 114,000 * (1 + 0.14) = $129,960. In year 3, this nearly $130k also grows at 14%: 129,960 * (1 + 0.14) = $148,154.40. Do this a couple more times to arrive at the final value of $192,541.46. The key here is that you earn 14% not only on the initial principal, but also on the gains from previous years.

With the above conceptual understanding, we can introduce a couple formal definitions for each: Continued…

Posted in Real Estate.


Secrets, URLs, and Logging, Oh My!

It’s interesting how as you move from “programmer” to “software engineer” so many little details evolve and start to take over.

The last few weeks I keep getting issues from my security team about logging “secrets” in URLs. So I want to explore how my view on this has changed over time.

  1. college student – just put your secrets anywhere in the HTTP request and GSD
  2. new grad – ok, I’ll use standard auth protocols (“Secure” Cookies, HTTP Basic, OAuth, etc) where I can.
  3. devops – no secrets in URLs ever! These get logged/recorded all over the place. Always put secrets in HTTP headers.
  4. senior eng – well actually… email validation, password reset, and similar APIs use one-time use tokens from email clients, so the tokens have to be in the URL. But as long as they’re truly one-time use tokens, they can be exempt from the above “no secrets in URLs” rule. Right? 😅
  5. today – security is concerned even with one-time use tokens, because if they’re not 100% guaranteed to be marked as used as soon as they enter our system (and they’re not), then there’s a chance they weren’t used and those are “live” tokens in some third-party system.

So now I’m trying to figure out the new, more evolved guiding rules here. Continued…

Posted in Tech Reference.


Restricting what packages are allowed to import in Golang using ASTs

I’m working on refactoring a monolithic end-to-end test suite for my company. It’s grown organically over the past 2 years as many, many new engineers and teams have onboarded. As you may know, “grown organically” is a euphemism for “it’s a hot mess”.

The question I wanted to answer today was “how do I restrict what packages my golang code can import?”

The solution I whipped up is a “linter” that runs as part of CI and fails if my import rules aren’t met. But what does it look like for real? Continued…

Posted in Tech Reference, Tutorials.


Initial Equity Grants vs Refreshes

I’ve been wondering why startups take a different approach for the initial grants in year 1 vs refresh grants in years 3-4+? That is, when you join you get a big grant in year 1 with no more grants for 3-4 years. But once you start getting refreshers, you often get smaller annual grants (that still vest over 4 years) instead of another big grant.

From the employees’ perspective, it would be much more exercise- and tax- efficient if instead of “a new grant every year” (with an increasing strike price) we were given another large 4 year grant with the lower strike price at the beginning of the refresh period.

I asked someone who’s been around a while and he said

This is something that is decided purely from the CFO’s and CPO’s perspective.

I’ve asked my CFO but haven’t heard back (yet?).

If anyone knows why startups treat refreshes different from initial grants, leave a comment!

In the meantime, I ran through a scenario to understand its implications a bit more. While doing this I realized that this also greatly decreases the number of shares. Maybe the assumption is that after 4 years, the options should be more valuable, the employees are already invested, or they’re just more likely to leave sooner. So maybe that’s why companies like it.

Let’s run through a comparison. Continued…

Posted in Personal Finance.


Engineering Growth

I was recently asked to prepare some statements for new hires at my company about engineering growth.

What does it mean to grow as an engineer?

This is a very personal question. The “right” answer seems to be “to increase your impact”. In reality, this often means working on projects with larger scopes that cut across multiple teams, doing more collaboration or systems design/architecture, and frequently less deep dive coding. But, just like not everyone wants to go into management, not everyone wants to coordinate across 3+ teams to get something done. That’s what makes this personal. Fortunately, especially at companies with a deep tech stack (e.g., infra/distributed systems), it could also mean understanding a particular area in extreme depth and becoming the go-to expert for this area.

Ultimately your goals are two-fold: you want to become the leader for a particular area of the product and/or tech stack and you want to drive it to market success in a way that is meaningful for the company.

Let’s break this down:

  • Leader – This doesn’t mean a title or position. It means that you’re the go-to expert, and that you have a vision for where the product or tech stack should be going, backed up with data and other supporting evidence. Most importantly, you know why this is the right direction and can communicate it well; you understand the benefits it will have to the team and/or the company. You continuously solicit feedback from your colleagues and industry at large to refine this vision, and collaborate across the company to ensure buy-in. And you successfully drive execution, either directly by your team, or by influencing other teams and their roadmaps.
  • Product/Tech Area – This could mean a single long-term project or product area, or it could mean a quick succession of small but meaningful wins. But this depends on where your product is in its lifecycle; the small rapid wins works well early in a product lifecycle, but to really advance in a more mature business or to the higher levels requires long-term ownership of an area meaningful to the company.
  • Market Success – It could mean a project that boosts the top line revenue, or decreases costs to boost the bottom line profit. It could be that it improves customer onboarding (thereby increasing the trial-to-customer conversion rate), or increases retention (thereby increasing the customer lifetime value). It could be that you create or re-work the major test suites to improve quality and decrease the number of incidents, or that you identify security risks and mitigate them before an attacker finds them. It could be that you improve developer tooling, increasing productivity so that developers can ship features faster.
  • Meaningful – There’s a lot of things that companies care about, and they evolve as the company matures. In the early days, its traction and product-market fit. Once you have some marquee customers, it becomes about stability and quality, expanding feature sets and reducing operational risks. As you mature, it becomes about operational efficiency, improving your margins, and profitability.

What are the top 3 things you think impacted your career? Tips, fundamentals, areas of focus, etc?

  1. I encourage every engineer to learn design patterns, that it’s one of the highest ROIs you get as an engineer. Languages, frameworks, and toolkits come and go over an engineering career. But design patterns are adopted and adapted through them. This starts with some fundamentals inside a single component (e.g., immutability vs concurrency patterns) and then progresses to patterns and designs that span multiple components (service-based architectures, techniques for avoiding cascading failures, level-based systems, actors, events/streams) until you reach a point where you can conceptualize entire systems.
  2. Another thing I advise that always sound very “old man” of me (even though I’m only 32) — understanding the history of technology is important. I don’t mean like the evolution from gramophone, to record, to CD…. Rather, what problems were service oriented technologies trying to solve? What did they do well at, and what problems did they create? What’s the difference between traditional config management and managing configs in containers? Why is Docker so popular, and what problems was it solving? What about k8s? What about streams, or functional programming? What kinds of problems is nodejs really good at solving, or golang, python, java, etc. and why? Really these things are just higher-level versions of fundamentals taught in CS school: what sort of problems is data structure X or algorithm Y best at solving. Understanding the why on these things is critically important to making the right decisions from first principles, and leads to higher quality software.
  3. Lastly, stay curious and prioritize learning. People understand that with investing, your money compounds every day. It’s the same with learning. If you spend a little bit of everyday learning and perfecting your craft, you’ll be leaps and bounds ahead in 5 years, and a totally different person in 10 years. Every time I move to a new company, it feels a bit like starting over. When I joined my current company, I didn’t know golang, docker, kubernetes, terraform, multi-cloud deployments, and so on. So while interviewing, I was on the lookout to see if I felt my future coworkers would be both smart and caring, both good teachers and good learners. This sort of “you teach me, I teach you” relationship enables the whole team to grow together. And as a result, we’ve all gained the experience of bootstrapping a new multi-cloud SaaS product from the ground up built on these very technologies.
  4. OK, here’s a bonus 4th tip. Remember that technology serves a purpose within a business. It’s a means to an end, not the end itself. If you can help bridge that gap between “what the business needs” and “what the technology can provide,” you’ll do well. A lot of technologists get caught up in the cool tech and miss the big picture. Always think of how does this benefit the company? As I’ve become fond of saying, “just because you can doesn’t mean you should.” Instead of thinking about individual tasks, think about the end-user experience. What problems are your customers trying to solve? What steps will they have to take with this proposed solution? What gaps will still exist? If you can speak the language of the product and that of your customers, your job will be that much easier. You’re more likely to build the right thing for your customer and your company.

Tell me a story about a period in your career when you felt like you grew the most.

When I started at my first company after school, it was a Series A-funded venture startup and I was a very early engineer (number 9, if I recall). All the other engineers were significantly more experienced. Our CTO and VP Eng had built and sold a company to Google (and then worked there for several years), and the other engineers were all very high-caliber. And I was just a kid out of school, so I had a ton of learning to do.

One of my first roles was working on a system to move a lot of data integrations (javascript “tags”) from the browser to send the same data server-to-server via APIs. We planned to build 100s-1000s of these integrations over time (and we did). One of the senior engineers had already built a POC using Apache Camel which was totally new to me. So, instead of just building “around the edges” on the framework he provided, I wanted to understand how Camel worked thoroughly. I knew we needed to make these integrations far simpler than they were to reach the scale needed for the company, and to do that we had to rework how we used Camel. So I started learning Camel from scratch to thoroughly understand this technology; I created a new Camel-based project, did a lot of different tutorials, made sure I understood the core components and knew what existed so I knew where to look more when the needs arose. And this understanding put me in the position later to help drive the first version of our zero-deploy style integrations, which was a huge leg up for the business.

Unfortunately, this youthful curiosity is sometimes lost over time. I encourage all engineers on my teams to hold on to it or re-discover it. This is vital to understanding engineering from first principles, which is necessary to continue growing as the technology industry evolves.

Posted in Tutorials.


The Relationship Between Marketing, Retention, and Income

My wife has started a women-focused coaching business, particularly around helping her clients improve their writing and communications. (Get in touch if you need help!) Many of her clients are entrepreneurs and the writing is particularly marketing-oriented. This has been fascinating and awesome to watch.

At the same time, she’s going through the entrepreneur journey herself, first by publishing her debut novel and now with the writing/coaching business. As she navigates the ups and the downs for herself and for her clients, I find myself trying to help by describing some of the trends, theory, and systems behind marketing and business growth.

One of the first “lessons” we had was about the marketing and sales funnel. At the time, I drew it out by hand, but it looked a lot like this:

Almost all of her marketing so far has been through social media. She launched her writing/coaching business at a one-week “vendor fair” on Facebook, and had already built up quite an audience on Facebook and Instagram over the last several years just by investing in her relationships.

With these initial sales, the “buyers” are typically 1st or 2nd degree relationships already. That means that they’re already aware of her — and often of her roles and skills as a writer, teacher, cheerleader, and confidant — so they have a degree of trust. This means they start their “buying journey” in the consideration or even purchase level of the funnel. Awesome!

However, as she ventured into her second “vendor fair”, the audience wasn’t as close to her. These were primarily 3rd degree connections, and thus will take more effort (impressions, visibility, persuasion, etc) to close a sale. Compound that with the fact that there were fewer 1st and 2nd degree relations to cheer her on publicly and otherwise advocate/testify for her, and she doesn’t have as much “social proof” to help close the buying gap.

Fast forward to today and she was telling me about the slow-but-steady trickle of book reviews that are still coming in. She seemed a bit disheartened that they’ve slowed down from the early days, but I told her this is to be expected with any “launch” based business model (like book publishing) and that it needed continued marketing to continue sales.

We started talking about the relationship between marketing “launches” or “pushes” and the resulting traffic, income, reviews, etc that result further down the funnel. Flashing back to my electrical engineering days, I described this to her as a “sawtooth pattern” and compared it to her desired “steady-state” stable income:

Marketing Launches vs Desired Income

This discussion led to something of an a-ha! moment (for me, at least :).

As a business owner, your goal is to find a way to transform the “marketing sawtooth” input into a stable “desired income” output.

Yes, this is a very engineering-oriented way of thinking about it. But business systems are just that… systems. More complex and nuanced than technical systems, yes, but fundamentally a business is still a system to transform some set of raw inputs (labor and/or assets) into desired outputs (a published book, happy clients, etc).

This is where the concept of the marketing funnel comes into play. By understanding this pipeline, including the conversion rates and lead time between each step in the funnel, you can ensure that you never end up in a “crunch”. In concrete terms, a crunch is when you don’t have enough business income to pay your bills or draw the income you (or your employees) need for living. This is shown as the red scribbled area under the green “desired income” line.

Tying it all back together, we were able to compare this to her piano business — she’s been teaching piano students for the last decade — and then to her writing business.

As a service business, and a part-time job, she can only have so many piano students at a time. So she has a waiting list of potential students. Sometimes, a student may be on that list a year or more before a “slot” opens up… usually due to a former student graduating high school, or sometimes just losing interest. Because she’s in demand, she can even fire advise the students who aren’t taking it seriously that it’s not a great use of their time/money, and immediately replace the lost income with a new student.

Likewise, the writing/coaching business is a part-time service business and she can only take on so many clients simultaneously. There are a few differences compared to her piano business, though:

  • The per-hour income is higher for writing/coaching services (around 3x)
  • However, the churn rate is also significantly higher (estimated around 6-14x). We don’t have enough data to quantify this yet, but I’m estimating a writing services customer lifetime of approximately 6 months compared to a typical 3-7 year customer lifetime as a piano student.
  • With piano teaching, the competition is typically limited to the local area. Compare this to writing/coaching services which can be done from anywhere, and prospective clients often have urgent demands based on their business needs. Thus, waitlists are likely easier to implement to help “smooth the sawtooth” into a stable income for piano teaching than for writing/coaching services.
  • This means that she’ll need to spend more time marketing her writing/coaching business, which eats into the time she has for servicing clients, and thus reduces her “billable hours” lower than if she had a waitlist.

Let’s do a bit of math. Plugging in realistic numbers, we can calculate the “customer lifetime value” (CLV) of a piano student vs a writing/coaching client.

  • Piano student: $40 per an hour-long session, one session per week, for about 40 weeks per year. Let’s say that she retains the average piano student for 3.5 years. The CLV of the typical piano student is thus $40 * 40 * 3.5 = $5,600.
  • Writing client: $200/mo for 4 hours per month. If the average writing client stays for 6 months, their CLV is $200 * 6 = $1,200. Note that this is the same number of hours per month as the piano student, and the rate is $10/hr more. But the total CLV is significantly less due to the difference in how long each client stays with her.

Does this mean that teaching piano is actually a better business? It depends.

To achieve the higher CLV also requires she dedicate significantly more hours over several years. Moreover, for my wife, she’s taught piano so long it no longer holds her interest like writing and coaching does. So there’s an aspect of personal fulfillment here.

Also, from a financial perspective, she’s early in her writing/coaching career and there’s a lot of optimizations and scaling techniques that she could use here, that likely wouldn’t work for piano teaching.

Using the same “framework” as above:

  • As she continues extending her services beyond “piece by piece” writing services to more clients that have her on retainer (or monthly subscription), she likely improves her client retention.
    • Potential CLV increase: if this increases retention to 18 months, the new CLV is $3,600.
  • If she focuses less on writing and more on personal or life coaching, as she has been with several of her clients, that’s likely to result in a much more long-term engagement, potentially on the same order as piano teaching but with a higher per-hour income rate.
    • Potential CLV increase: if this increases retention to 3.5 years (to match piano students), the new CLV is $8,4o0.
  • If she builds a (commission-based) team, she can leverage her time to serve more clients. Then she’d be responsible for marketing, customer relationships, and quality assurance. Eventually, she could even hire team members to help with these activities as well, growing this into a standalone business that could potentially be sold one day.
    • Potential CLV increase: if she does a 50/50 profit share with a writer/coach and retains a customer for 18-months, the new CLV is $1,800… but she’s unlocked scalability. She’s able to grow her business beyond the confines of the number of customers she can personally serve. Her new bottlenecks are around the number of customers she can find and the number/quality of people she can recruit.
  • If she builds a writing or coaching community, she can leverage intra-client relationships to make her services even more “sticky”, increasing retention and at the same time increasing the likelihood of referrals from existing clients.
    • Potential CLV increase: if this increases retention to 5 years and every 3rd customer refers in 1 additional new customer… well this business has potential. :)

These goals serve to ensure high client retention, which reduces marketing effort, which allows her to spend her time focusing on what she does best — helping clients. And this is better for her too, increasing the amount of “billable” hours she works which, when providing services which command a higher per-hour rate, increases her total stable income given the same number of working hours per week.

All that is to say, this is a very exciting time in the Ray household. :)

Posted in Personal Finance.


Preventing CSRF attacks on a Single Page App with REST API

SPAs vs CSRF Blog Header

tl;dr – If your SPA uses a private REST API, use CORS and a CSRF Token header. If your SPA uses a public REST API, use a SameSite Strict cookie for mutating operations (if you only support newer browsers) or separate API security domains (if you support older browsers as well); public API clients just use OAuth Bearer tokens.

The world of web app security is a strange place. It’s a bit like playing whack-a-mole, because one security measure may often introduce a new security hole.

This post walks through the CSRF-vulnerability analysis I did recently for my company, and the thinking that went behind it. In particular, we wanted to ensure that our React-based app is secure from CSRF attacks, even though the backend REST API doesn’t require CSRF tokens.

CSRF

Let’s start with Cross Site Request Forgery (CSRF). This is when a malicious website is able to perform actions on your web app within the context of a logged-in user. This happens because your browser helpfully sends your auth credentials along with the request, which is how the site knows that you’re still logged in. Most of the time, this is an HTTP cookie, but you can also be susceptible with any user agent -managed credentials (such as HTTP basic auth, HTTP digest auth, or even mTLS).

How do you prevent this? Your first stop when dealing with any web app security should be OWASP; sure enough, they have a whole guide to CSRF prevention. The traditional mitigation involves generating a CSRF token on the server and added as a hidden form field during server-side rendering.

But how does this work for a modern web development stack, where you have a javascript  “Single Page App” (SPA) frontend backed by a REST API? Continued…

Posted in Tutorials.


CLI Design Best Practices

Having chartered and led my company’s “CLI Foundations” team, which built and owns their primary two CLIs, I’ve spent a lot of time thinking about CLI design. So when I stumbled upon this tweet today, I had to jump in:

There’s so much thought and effort put into “User Experience” design for the web UI, mobile experience, etc… but somehow the CLI experience is often overlooked. For companies and products with a technical audience, this is a huge gap in their product offering.

The answer to the tweet’s question, like everything in engineering (and product, and business), is “it depends”. The right CLI design for your product starts with understanding the answers to these questions:

  1. What’s the scope of the CLI functionality?
    1. Is this a special purpose tool, or a complete toolbox? If you have new needs, will they be new CLIs or new commands in the CLI toolbox?
  2. Who are the intended users?
    1. Do your users primarily spend their days writing code or running the system?
    2. Is this CLI intended for use by beginners or advanced folks?
    3. How often do you expect users to interact with your CLI, based on the common use cases its designed for? (Do they only use it once during onboarding, occasionally, or regularly — monthly, weekly, daily)?
    4. What operating systems do they primarily use, and what dependencies are they likely to have installed? (Any browser or Chrome v80+, a Java runtime, etc?)
  3. How do you users want to interact with your CLI?
    1. Do you want to support users scripting around your CLI? (e.g., CI/CD)
    2. What sort of workflows should you support? (e.g., interactive, imperative, declarative, gitops, etc)

Just like traditional UX (for a UI), this will take time and evolve along with your understanding. Getting to the best design will involve talking to customers and sales/field reps to understand what your customers need today, and working with your product and business development teams to understand where your market is going and what your customers will need tomorrow.

That being said, this should be may be easier for a CLI than it is for a UI. In theory, your customers are technical enough to know what a command line is, and seek out a CLI tool to solve their problem. There are some industry-wide design patterns that almost all CLIs follow (e.g., --help on any command) and these are no brainers. Within a particular market, you may have competitors which you can study and learn from.

And lastly, most CLI functionality should generally mirror the concepts found in your UI, product documentation, etc. to minimize the learning curve for your users. The easiest way I’ve found to do this is to make your CLI resource-oriented, just like the REST API that’s probably backing your CLI. :)

Ok, enough theory. Let’s go through a concrete example.  Continued…

Posted in Tech Reference.


Salary Growth vs Earnings Growth, or Why the Wealthy are Entrepreneurs

Several years ago, I discovered that you could buy small businesses from their founders at a reasonable price. The size and nature of many of these companies make them very attractive as “lifestyle businesses”, or businesses that require part-time effort to operate and can yield good-to-high income for the owner’s living expenses.

Why is it that businesses are so much more powerful as cash generators than a “job”? One thought is that you can potentially disconnect your income from your time spent. But today I realized something else:

Its easier to grow earnings for a small business 10-15% year over year than it is to grow “day job” salary at the same rate, over the same time frame.

In my fortunate career, I’ve managed to grow my salary at 9% per year for almost the past decade, which is great. But I don’t know how long I can keep this up before I hit a “salary cap” in my field, or have to move to Silicon Valley to continue growing my income.

Now, I would be remiss to not acknowledge that many small businesses never make it to this stage; they’re but an extension of their owner (e.g., service based businesses) and lack time leverage as the owners are still trading time for dollars.

But a skilled operator in the right business is quite capable of growing a small business at a double digit rate for most of a career. (Sanity check: if you start out at a typical $60k/yr, a median household income, and grow at 15% for 10 years, 12% for 10 years, and 10% for the next 10 years, you’d be doing just shy of $2M per year at “retirement” after 30 years. That’s very achievable by many “dull-normal” Millionaire Next Door businesses. And that business could be worth between $4M and $12M if you decide to sell it then. Wee!)

This is a very different approach than the venture-capital fueled “grow at all costs” mentality that’s currently in-vogue. Fortunately, this mindset is starting to gain traction in communities like IndieHackers and MicroConf.

And this approach may be just right for your own life. :)

Posted in Ramblin' Thoughts.


House Hacking: A Real Life Example

There’s a ton of interesting articles on BiggerPockets about House Hacking. But I hear people saying it doesn’t actually work, or its not worth it, or you can’t literally live for free. So here’s the real-life numbers from my very first house hack, back in 2015.

Numbers at a glance:

  • Purchase PriceWe bought the property for $300k with a 10% down FHA loan
  • Rental Income: $1000/mo rent from unit 1 and $1100/mo rent from unit 2
  • Mortgage, Taxes, Interest: $1800/mo mortgage (including taxes and insurance)
  • Repairs & Maintenance: A popular rule of thumb is that 1% of the purchase price will go to repairs and maintenance each year (on average); that’s $3k/yr
  • Vacancy: We’ll assume 5% vacancy when the sits empty for a couple weeks between tenants. That’s $1,200 we won’t get.

If we add this up, that’s $2100/mo in rent from the tenants, or a total of $25,200 for the year. After subtracting for vacancy, that leaves us with $24k in income.

On the flip side, we’ll pay $21,600 for the mortgage, insurance, and taxes. Add $3k for maintenance and repairs, and we’re at $25k in expenses.

We got our own apartment for a total of $1000 per year. Sweet!

But does this mean the naysayers are right? That this isn’t really living for free? NO! It’s wayyy better than that!

Fortunately, there’s more to the story. :) Continued…

Posted in Real Estate.




Log in here!