Is 0% APR loan from Affirm a good deal?

Short answer: No.

But it is fairly subtle as to why.

Background

I recently was making a big online purchase, and the merchant offered “12-month 0% APR financing” of the purchase through Affirm.

I thought “why pay for something now if I can pay for it in 12 months?” and decided to look into this.  Since I bothered to think through this, I thought I’d post the analysis in case someone else can benefit.

Analysis

First, the deal seems to be legit.  Going through the process, it genuinely appears that they’ll do the transaction as a 12-month loan with 0% APR instead of upfront payment. Looking at the structure of the payment plan, you make equal payments monthly. So in reality, you’re really borrowing for a weighted-average of 6 months.

However, even a credit card that you pay off in full each month is borrowing for ~1.5 months in the usual case. On average, you are ~15 days from when your statement next closes; and then the payment is due 30 days after that.  So you’re already borrowing the

Benefits:

  • time-value of your month: 1%. This is return earned by your money over the time between when you pay back the loan (~6 months) and when you would otherwise pay for it (~1.5 months).  Assume 3% annual after-tax return, which is arguably optimistic at the moment. Doing the math : 6 – 1.5 = 4.5 months that you’re really earning that return for, so you’d expect to earn 4.5/12 = ~1% return on the value of the purchase.

Costs:

  • Forgone credit card rewards: 2%. Because you’ll pay the Affirm loan off with ACH transfers, rather than a credit card.
  • Forgone credit card protections: ??. purchase protection, disputes, etc.
  • Value of your time/energy: ??. Marginal complexity/hassle for you to administer a loan in addition to your credit card.

In summary, if you can pay for the purchase on a credit card with decent rewards that you’ll pay off in full, you lose money from this loan in practice. Roughly, 1% of the value – depending on your card’s reward value and your beliefs about after-tax rate-of-return.

Is Amazon Web Services “too big to fail”?

To borrow some financial market metaphors, it’s hard to argue that cloud providers aren’t a “systemically important” part of the Internet.  If one fails catastrophically, it’s more probable than you might think for others to quickly follow.

Compared to 10 years ago, Infrastructure-as-a-Service (IaaS) has greatly simplified web engineering.  Gone are the days of assembling and racking servers – experiences that every start-up experienced in the 90s and even well into the Web 2.0 era.  But any simplification involves trade-offs, and the rise of IaaS is no different.  One to consider is reliability.

With IaaS, you’re outsourcing a good chunk of your reliability to a 3rd party.  They give you an SLA, which at best compensates you for outages, but it’s usually limited  to what you’re paying them – not the true cost to your business of the outage.  At best, the SLA aligns interests a bit; they suffer when they cause you to suffer, albeit it not as much.  In practice, this often works OK.  Cloud providers are pretty reliable, and its very difficult for any young engineering team to credibly claim that their home-grown systems architecture is going to be more reliable than Amazon Web Services (AWS.)

But what if AWS isn’t reliable enough for you?  A straightforward approach is to avoid being dependent on AWS, which is appealing for cost and lock-in reasons in addition to reliability.  If AWS fails, you’ll quickly failover to Google App Engine (GAE), Azure, etc, right? But what happens when a lot more AWS users opt for the same approach? Then an AWS failure becomes a huge load increase on GAE, which could trigger it to fail as well.  The probabilities of AWS failing and GAE failing are not independent.

That is a subtle point: The probability that AWS fails is low.  The probability that GAE fails is low.  The probability that GAE fails, given that AWS fails, is not as low.

And it’s hard to predict. How many AWS users have disaster scenarios where they migrate to GAE?   How significant of an AWS failure would it take to cause them to invoke these failover procedures? How much spare capacity does GAE really have?

The logic above applies to all cloud platforms, not just GAE. The general reasoning is simply that there’s a relatively small set of major cloud providers, such that if a big one fails, so might others.  

The more fragmented and commoditized the cloud infrastructure market is, the safer we all are. As long as AWS is the dominant player, you’re better off – from a reliability standpoint – picking someone smaller and relying on AWS as your failover.  At very least, should your primary provider fail, you’re maximizing your chance that the aggregate hit to your failover will be manageable.   

Separate Work and Play with Multiple Chrome Users

If you use Google Apps both personally and professionally, you should set up a distinct Chrome user for each context. It works much, much better than having multiple Google accounts authenticated within the same browser instance.

The Problem

Although Google supports being simultaneously logged in with Google accounts, the UI for switching between authenticated users in many services isn’t graceful. You go to gmail.com, often find yourself in your personal account, and need 2-3 clicks to switch it to your professional account . Even once you’ve done this for Gmail, opening a link to a Google doc might open Google docs in the other context – and even give you a permissions error that your personal account can’t open that document.

The easiest solution was to log into only one account at a time and to minimize switching between your personal and professional contexts. That’s probably a good habit for other reasons as well, and was mostly what I did during years of formal employment.

However, a couple years ago, when I activated two factor authentication on all my accounts (which I highly recommend), logging in and out several times a day became a much larger hassle. For the last few months, I haven’t been formally employed, so I’ve been switching in and out of professional and personal contexts even more frequently.

The Solution

Google Chrome supports multiple users. For years, my wife and I used these on shared devices to separate our accounts. I hadn’t before thought to use them to separate my own accounts into multiple users.

I set-up multiple Chrome users — one for my personal Google account and another for my professional Google Apps account. Handily, Chrome visually distinguishes users with an avatar, shown in the upper left of any browser window. Clicking the avatar allows you to launch a new browser window in the context of another user, which is simpler and more consistent than how this is implemented within individual Google web apps.

2014-02-03 Screenshot for Blog on Chrome

Some Windows specific stuff:

  • multiple browser windows for the same user stack separately on the taskbar, with the avatar overlaid on the Chrome icon
  • you can create shortcuts that directly launch Chrome in a user context
  • pin to the shortcuts to the taskbar by dragging them there; pinning an active browser window will pin the Chrome application, which won’t necessarily launch in the user that was active when you pinned it

More Benefits

Clear Visual Distinction between Work and Play

Once I adjusted my bookmarks bar, extensions, and user avatar for each context, I found that the browser windows look visually quite distinct. Mentally, I think this can only help focus and avoid procrastination. My personal email is no longer just one click away, staring at me. It’s less likely that when I get stuck on coding problem for a moment, or otherwise distracted, I’ll reflexively click into my email, find something new, and turn a 30 second distraction into 5-10 minutes.

Separate Sets of Bookmarks

I used to mix personal and professional bookmarks into one bookmarks bar, which I sync’d between Chrome installations on different devices. Once you have distinct Chrome users for each account, you can have a set of professional bookmarks and a set of personal ones. It provides more toolbar real estate than you could otherwise allocate to each context.

Limit Extensions by Context

Again, this is useful in supporting a strong mental separation of your work vs personal context. But it’s also a security issue. A lot of Chrome extensions have permissions to see and access every webpage you open. Why show them more than you need? If some extensions are only relevant in one context or the other, keep them there. At very least, you’ll minimize the potential scope of private data that a malicious/invasive extension will see.

5 Tips for a New Codebase

Lately, I’ve been thinking about starting new repos for some projects and looking at a few different start-ups’ code. Below I’ve captured a few quick tips on starting a new codebase:

1. Use English.

The best engineering talent in the world reads and writes english. It’s a prereq to keeping up-to-date on the latest technologies or contributing to open-source projects.

At some point in the future, you might want to outsource something, have a consultant advise you on some aspect of your code, or even sell your company to someone else. Why limit potential partners to those who only speak your local language?

2. Tabs not spaces.

Or the reverse. I don’t care – the point is don’t waste time arguing or researching issues that are 90% arbitrary questions of taste. Anyone who emails your team list about changing should be fired. Or at least forced to buy everyone else a beer.

3. Git not Hg.

It works. More importantly it’s popular and well-known. Why make people learn something new to work for you if the “standard” tool is just as good? I prefer the elegance of Hg, but it just doesn’t have the following that Git does.

4. Use known code standards.

Don’t write your own. Having done so a couple times, trust me: you have more important things to do. Most engineers will imitate what they see in your code base, rather than spend time reading your standard. To find a standard to reference, Google Style Guides is a good place to look; or your favorite open source project; or the engineering blog of your favorite company.

5. Document in code, not in a wiki.

Wikis are chronically incomplete and out-of-date. The best way to write documentation of what your code does is in the code itself.
It’s the first place whoever needs the documentation is going to look.
The documentation will follow the code through the workflow. You don’t need to worry about a developer making changes on a branch that has yet to be merged to live. When it’s in live, the documentation on live will be updated.
It’s easy for the reviewer to verify that someone changing code has properly changed the documentation.

Conclusion

A common theme from these: while the “clean slate” of a new project or company might seem like a great opportunity to follow your own preferences on issues like the above – be careful. Indulging your personal preferences can come at the cost of lengthening the learning curve for those who join your project in the future.

Google Spreadsheet Locales for an International Company

Tuenti, where I work, is a Spanish company, based in Madrid, with an English-language working environment.  One particular problem this causes is how to format dates, numbers, currencies, and spreadsheet functions.   We use Google Apps for everything – and within Google Apps, formatting conventions pose the biggest challenge in spreadsheet.  If some people are creating spreadsheets with Locale=Spain, and others with Locale=United States you have some serious problems: dates are entered erroneously, you must constantly switch how you type numbers/functions, and copy-and-paste creates multiple layers of issues.

My solution to reach a sane standard:

1. set Google Spreadsheet locale to UK (see Google Spreadsheets Help on Locales). This gives the EU date format convention (dd/mm/yyyy), the decimal point (period) as the decimal mark, and the comma to separate function arguments. Unfortunately, it creates the problem of having the default currency as GBP; buries the option to format in EUR several levels down in the UX, and completely removes option to format in EUR rounded. Therefore, you must

2. use a Google App Script menu to format values in EUR (€). Google App Script is immature and a bit buggy, but it allows you to easily add a custom menu to a spreadsheet, from which you can invoke a function that will apply a format to the “active” (selected by the cursor) in the spreadsheet.  This is exactly analogous to the UI of the native formatting functions Google has in the toolbar by default.

To accomplish this, I wrote a simple App Script to format cells as rounded euro values, following English conventions (eg “€1,000” rather than the Spain default of “1.000€”). It is available in the App Script Gallery (or will be, once Google approves it). To add it to your spreadsheet, follow Google’s instructions on Installing a Script from the Gallery.

While you can look at the code yourself from the gallery, I’ve also included it below in appendix 1.

Appendix I: The Code

 

Here’s the code of the script; it is pretty simple, but it’s about as much coding as I get to do these days. I’ve structured it to be extensible to add a lot of custom formats, using the syntax/semantics defined in appendix II.  Feel free to adapt it however you wish.

/*
 * format active range as EURO round, comma separator on thousands
 *
 * why? bc if you're using English in the spreadsheet, but
 * want to use euros as units Goog lacks a direct way to format it
 *
 * placement of currency sign is language dependent, not currency
 * dependent; a spreadsheet in english should have EURO-sign before
 * the number, not after.
 * http://en.wikipedia.org/wiki/Linguistic_issues_concerning_the_euro
 */
function formatEuroRound() {
  applyNumberFormat("€,###");
}

/**
 * applies a numberFormat to the active range
 */
function applyNumberFormat(formatString) {
  var range = SpreadsheetApp.getActiveRange();

  var format = [];
  for (var i=0; i < range.getHeight(); i++) {
    format[i] = [];
    for (var j=0; j < range.getWidth(); j++) {
      format[i][j] = formatString;
    }
  }

  range.setNumberFormats(format);
}

Appendix II: Number Formats

The Google App Script documentation of the Spreadsheets Service describes the setNumberFormat  method, but doesn’t provide any guidance on what the syntax/semantics for the formatString parameter is.  It appears that number formats in Google Spreadsheets follow some historical conventions they’ve inherited from Excel – and I presume other places.  A decent forum post directed me to a spreadsheet giving numerous examples of formatting strings.  You can look at that, in combination with the applyNumberFormat() function I gave above to create arbitrary formatting functions.