Posts Tagged With: Today’s World

Sour Punch Strawberry changed their formula

I have a sweet tooth and one candy I really enjoy is Strawberry Sour Punch.

Unfortunately after twenty years of having the same formula it seems that the company has decided to change the formula for Sour Punch. The new candy has more of a cherry flavor and isn't as sour. It does not taste good at all.

The company confirmed that the formula changed in a DM:

Due to the global supply chain crisis, we’ve had to temporarily tweak our formula. We know the current product isn’t what you’ve come to expect from SOUR PUNCH, which is why we are doing everything we can to return it to its original deliciousness so that you can enjoy the candy you know and love.

People on Reddit have confirmed the new flavor is hitting shelves. Recent reviews on Amazon are not pretty.

Have you had a bad batch of Sour Punch, or a batch with a different flavor? Leave a note in the comments, or contact the American Licorice Company and ask them to bring the old flavor back.

Liked what you read? I am available for hire.

Get Urgent Care from One Medical

On Sunday morning at 1am I had a lot of stomach pain. I am a One Medical customer, had heard that they offered urgent care, and so I searched on their website for information.

Unfortunately their urgent care option does not show up in the list of care options on their website:

I concluded that their urgent care offering didn't actually exist and paid for a competing provider's product, so I could talk to a doctor at 1am.

This morning I was informed that their urgent care option does exist, but only in their mobile apps. So you have to go into the iOS app and then you will see "Video Call Now" as an option.

This is a baffling design choice to me. I don't understand why, as a company, you'd only put features in one of the several ways customers can use your product. Or at the very least you could put "Video Call" in the list of options on the website, and then have a popup that says "open the app." But they didn't do that.

So if you are looking to get urgent care or use any One Medical feature try the app.

If this post was useful please send the One Medical twitter account a DM saying so so they can update their product.

Liked what you read? I am available for hire.

Ten years of experience, still failing phone screens

I fail phone screens pretty often, which limits my job prospects and is embarrassing for someone with ten years of industry experience, a pretty extensive Github account and a publicly available list of difference-making projects. 1 In theory a phone screen is supposed to evaluate whether a) this person would be good at the job being hired for and b) whether it's worth investing another five hours in trying to hire this person.2 In practice I think phone screens are pretty poor at screening candidates for fixable reasons.

I spend a lot of time setting up my development environment to get a fast feedback loop. If I write a little bit of code I want to know immediately whether it works or not. There are a lot of components that go into this, but generally, this involves being able to type quickly, have builtin editor support for building code, checking function definitions, and being able to background and foreground the terminal constantly to run tests or test scripts. All of that means I'm constantly able to exercise the code I'm running and get feedback about whether I'm headed in the right direction or where problems are. This is a pretty significant advantage for me and I can work more quickly than most engineers I know.

A lot of this effort was inspired by Gary Bernhardt, who has a video series that really changed the trajectory of my career and might change yours as well. Gary is extremely fast and is obsessed with test speed. Fast tests mean that he can get feedback on whether the code he wrote works a few hundred milliseconds after typing it.

Most phone screens involve implementing some fairly complex algorithm3 in one or multiple steps on Coderpad, an online text editing tool. With Coderpad you get a single file that you have to put all of your code in, and you can't load data from any external files. Most companies don't let look at any reference documentation either so you have to know the standard library API's cold or guess until you get them right.

Coderpad must work for some people since companies are able to hire a nonzero number of engineers, but it is definitely not a good fit for me. I'm not fast at reasoning about code, and I often make trivial mistakes just trying to get a "first draft" of a program out. If I get behind or the interviewer starts interrupting to ask about the bad code I'm writing I get very stressed and have trouble both listening to the interviewer and trying to address the issues with the code.4

The lack of any sort of feedback loop just totally compounds the problems. Most of the questions you are asked don't have a lot of different inputs, and have outputs that are 100% a function of the inputs, which are perfect for writing fast, table driven tests. But a lot of interviewers will explicitly tell you not to write tests, or in some cases even disable the ability to run the code, a Coderpad "feature." So you have to keep the different branches in your head and the different states the code can be in as you re-enter a for loop or whatever, and then figure out which of these changed when you did any sort of refactoring.

Objectively the screeners are making a good decision to fail me,5 I probably look like I have no idea what I'm doing and I'm only sometimes able to get a good result by the end of the interview. But this is a bit like declaring someone a bad sous chef after asking them to bake a rare pastry without a recipe. I am more likely to get an offer from an onsite interview than I am to pass an initial phone screen, which seems backwards.

I don't think that "can you code" algorithm implementation is the best thing to spend your entire hour evaluating during a phone screen, but even if you think it is, there are ways you can improve it significantly. Actually add a set of tests or allow the candidate to write or run a test suite, or run code in their own text editor and paste it into the Coderpad at the end. Offer the option of a harder question that still has a time limit but can be completed without having someone watching over their shoulder and asking whether that variable name is really necessary.

Anyway, I think a better idea would be to try to spend a shorter amount of time evaluating a larger range of topics. Triplebyte has a quiz that actually does a pretty good job of this; you get asked thirty or so questions about databases, networking, and simple coding questions ("what is the value of 'a' when you get to line 17?"). The last time I interviewed I took their quiz and did well enough that I was able to skip directly to onsites at every company they work with. Most of the value that Triplebyte provides comes from ensuring companies don't bounce good candidates by a bad phone screen or poorly calibrated interviewer; it's essentially a way to hack bad internal processes.

Besides the fact that people like me get extremely stressed implementing a new algorithm in a time limit without being able to exercise the code, while someone is watching and asking questions, there are diminishing returns to spending the 30th or 40th minute on the same topic, and this is such a tiny part of your job anyway. It would be better to try to ask a larger number of easily gradable questions that represent stuff most people will do in their jobs, and will give you more signal in a number of different directions. Some ideas:

  • Clone this source code repo and tell me (what timeout is set for X third party API/what endpoint you'd need to hit to do Z/any other information in the repo that can be determined with a yes/no answer).

  • Say you have a function that checks whether three integers are even numbers that increase. What tests would you want to write to tell whether it's true or not?

  • Why is it bad to write a file to the disk one byte at a time?

  • What can happen if you leave a database transaction open for a long time?

  • Here's a CRUD app, copy existing code patterns to implement a new CRUD endpoint (to be honest this is like a huge part of the job at most companies.)

  • Here's a stack trace from an open source project, can you tell me what went wrong?

  • What's a data race? Here's some simple code with a data race, can you tell me where the problem is?

  • Let's say you have a database table with a user ID and a balance denominated in integer numbers of cents, what's a SQL query that could charge ten dollars to the user's account?

  • What are some examples of good and bad production alerts?

  • In a few sentences, how does UTF-8 represent different types of characters?

  • Here's a HTML template with an XSS, what would you need to type into in the email address form to get an alert to pop up on the screen?

And others.6 You could have a rubric for each question, then add up the scores or require X number of nonzero answers. I think you'd get a better sense from those questions than you would a single 45 minute algorithm question of whether someone would do a good job at your company.7

1. Recently I had a phone screen at a company you've heard of go poorly and then have a VP intervene internally because the phone screen feedback made no sense based on my track record.

2. Another fallacy people tell themselves about the phone screen is "it's just to tell whether candidates can program" but if this was true interviewers would not fail people for correctly coding the brute force solution, or they'd more often provide the instructions for implementing an algorithm, which they never do.

3. I'm far from the first person to talk about this but the focus on algorithms just baffles me given how rarely you need to implement a complex algorithm in actual production code. Here's a job queue and a scheduler that's about 5000 lines of Go code and probably the most complex thing that happens is a for loop. There is a lot of thought that had to go into the API design to avoid long running transactions, and a lot of work that went into finding a fast and correct version of the dequeue query, but you'd never test for those in a phone screen, as currently designed. Another project I worked on for a client is a fully featured Twilio API browser, 9000 lines, that again does really not have any code that's as complex as would be tested in a phone screen. I used an LRU cache in one place, but I used an implementation that Brad Fitzpatrick wrote, there's no reason to write that myself.

4. This also happens when people ask me to write code on a whiteboard but that doesn't happen anymore due to COVID, and anyway I just tell companies that I need to write code on my laptop or I'm not going to do the interview and they will generally let me do that.

5. I shouldn't rule out the possibility that they are making the right decision and I am in fact bad at engineering. Certainly there are a lot of confident, mediocre tall white men in the tech industry. That said, I ran a successful one-person consulting business for several years, and presumably if I was not delivering more value to each company than I was invoicing, the companies I was working with (Segment, Notion, ngrok, One Medical) would not have renewed my contract multiple times.

6. If this sounds interesting, and you'd like help designing a phone screen experience that's tailored for your company and the types of experience you want to screen for, get in touch!

7. I have a bunch of ideas around testing how quickly and how accurately people can type, or accurately transcribe text from a second screen, that I think could be decent predictors of job performance but I'm not sure are fair to test out in a professional context without academic research that could validate them at least a little bit.

Liked what you read? I am available for hire.

Different Realms, Different TLD’s

Many companies break up their internal environments into different realms. A typical setup might look like:

  • The prod realm is where production servers live.
  • The dev or stage realm is a live testing environment, where code gets deployed before it goes into production, or long-running features are tested.
  • The local realm is for code that's developed on your laptop, or in Docker, or in a cloud server provided to each developer.

The names each company assigns to each realm might be different, but that doesn't matter. I strongly recommend purchasing a different TLD for each realm that you operate, and then deploying them everywhere your company accesses sites over HTTP. So following the example above:

  • acme.com serves your production site.
  • acme.dev serves your development realm.
  • acme.app, acme.site or acme.website is reserved for your local realm.

You might need to change the TLD's based on which ones are available, but since there are hundreds, you should be able to snag three. The key is you need to be able to buy the same hostname for every TLD. You want things to be as simple as possible for your team - no needing to remember that the prod website is acme.com and the dev website is acmetest.dev or whatever. Then it becomes dead easy to remember how to navigate to each site - you combine the hostname and the TLD for that realm, and then you get to the right place.

For local development, you're probably going to be redirecting traffic to your local machine, instead of using the public Internet to serve it. You want to buy the domain anyway because you don't want someone who forgot to redirect traffic to end up sending requests to a server you don't control.

There is a special TLD named .test that is designed for local development and DNS testing. However, Google forbids the use of that domain for e.g. SSO authentication, so I recommend buying a live domain and then black-holing the traffic.

I wrote a tool called hostsfile that you can use to automatically add entries to the /etc/hosts file on employee laptops, to redirect their traffic from your "local" domain to localhost.

sudo hostsfile add acme.app 127.0.0.1
sudo hostsfile add acme.app fe80::1%lo0

Why are separate TLD's so important? Besides the fact that it's drop dead easy to remember, there are a few good security reasons. The goal with many security measures is to make entire classes of problems impossible, and that's what this strategy does.

It's impossible to "leak" a production cookie to your dev environment, or vice versa, if you have completely separate TLD's for each realm. If you use www.acme.com for prod and dev.acme.com for dev, you need to host the DNS records for each realm in the same place, which makes it difficult to test changes, and increases the likelihood of accidentally shipping a breaking change. With different TLD's you can use different Route53 realms, or different accounts with your hosting provider. These make it easier to test changes without accidentally breaking production.

Another way that cookies break is because your prod dashboard is served at the root - acme.com - while your dev and staging servers add an additional subdomain, for example dev.acme.com. This can cause subtle breakage; if you use the same hostname scheme in every realm, it's impossible.

I encourage teams to use TLS for local development, for the same "just keep everything the same between all realms" reason. If you are reusing TLD's, you could potentially issue a cert that's valid for a production domain, or be tempted to reuse your production certs for local development. If you own acme.website and only use it for local development, and use acme.com for prod, it doesn't matter if you leak the .website certs accidentally, because you can't use them to do anything that matters.

Finally, it makes it very difficult for people to accidentally confuse what realm they think they are on. If you make a request to .website you know you are not in prod, for example.

Liked what you read? I am available for hire.

Fast, Parallel Database Tests

Here are some of the different strategies you can use to write tests that read or write data from a database, and the benefits and drawbacks of each. I'm usually writing Go code, so the examples here are for Go, but the notes should generalize to any language that runs tests against Postgres, MySQL, or any other database.

At a high level my goal is for the tests to take a minimum of programmer time. Programmer time is spent on the tests in a few different places:

  • Writing tests.
  • Running the tests.
  • Troubleshooting test flakes.
  • Troubleshooting written tests that don't behave the way you expect.

Our goal is to minimize the amount of time spent across all four of these areas, from which I have the following principles for a test suite:

  • Tests should be fast. Each test should do only what it has to do, which for database tests primarily means it should only create the objects it needs to test the behavior it needs to test, and no more.

  • Tests, and test packages, should run in parallel, which usually helps the test suite complete more quickly.

  • Tests should be predictable; if tests return unpredictable results, or interact in bad ways, this leads to wasted time tracking down why the tests are failing.

Obviously these are in conflict - parallel tests are less predictable than sequential tests - but there are some things we can do to make tests fast and predictable, and some common techniques that make them slower and unpredictable.

Don't: Reuse the same fixture objects in each test

You might have a set of "standard" test objects that get written to the database — Alice and Bob, and maybe Alice is a power user and Bob just signed up. If you try to create them in a test and they exist in the database already, the tests will upsert them.

This is fine, and you can do it, but it tends to break down in two ways:

  • "Default" fixtures tend to accumulate new database objects any time you create a new table, like a snowball rolling downhill. This means any new table makes all of your tests slower.

  • If you run tests in parallel, any test that updates or deletes any fixture that other tests rely on can cause unexpected behavior.

Because we are optimizing for programmer time - fast tests, and no unexpected behavior during tests - I tend to want each test to create the objects it needs, and make them each unique.

Don't: Reuse the same set of ~500 names

When you use a library like "Faker" to create objects that are sort of similar but have a common set of variations, for example, a last name derived from the same set of 500 last names, you are bound to run into trouble. It's way too easy to accidentally create two test objects that have the same birthday or same last name, when you didn't expect that to happen, and as a result, end up with one result when you wanted two, or otherwise get test failures that only occur once every 500 runs.

I've previously discussed why Faker is a bad idea, read the post for more.

Do: Use UUID's for anything that needs a "random" or unique input

Instead of creating "Alice" with 1 of 500 pre-seeded last names, or always with the email address "alice@example.com", use UUID's (or a part of a UUID), anywhere you need unique data. So "Alice Jones-a9706630", with email "alice-7cce0183@example.com". The first 8 characters of a UUID have 4294967296 different values; these objects will not conflict with each other during your lifetime.

Don't: Truncate the database after each test

At the end of each test, you could issue a command to truncate or delete all database tables. So each test is something like:

t.Run("TestAccountCreate", func(t *testing.T) {
    assertEquals(t, user.ID, 7) // or whatever
    cleanup(t)
})

The advantage to doing this is that each test cleans up after itself - you can create the same objects in multiple tests even if they might fail a uniqueness constraint, since it gets destroyed between each test instance. The disadvantage to doing this is that you can't run tests in parallel, because one test might issue a truncate right when the other test is writing to the database.

Further, it's not uncommon for tests to hang, or crash, while they run. If that happens, your truncate-after-test runner will not actually run, and the next test will encounter an inconsistent state. These types of failures can be tough to troubleshoot because the failure was actually in the previous test, which your test output might not make clear.

Don't: Truncate the database before each test

This has most of the benefits and drawbacks of the previous section, except you need to truncate everything in the database, because you don't know what test ran before this one. In theory, if you delete after, you only need to delete from tables that you wrote to.

Don't: Truncate the database after each package

You could enclose all of the tests in a parent test, something like this:

t.Run("Package", func(t *testing.T) {
    setUp(t)
    t.Run("Test1", func(t *testing.T) {
    })
    t.Run("Test2", func(t *testing.T) {
    })
    t.Run("Test3", func(t *testing.T) {
    })
    cleanup(t)
})

This way, you only pay the penalty of database setup and cleanup once per package.

However, the default for Go tests is to run as many package tests in parallel as you have CPU's available. So one package may be just finishing on one CPU (and truncating the database) when another package is starting on a different CPU, which causes failures that are hard to troubleshoot. You can set -p 1 to disable package parallelism, but the test suite gets a lot slower if you can only run one package's tests at a time.

Don't: Truncate the database before each package

This has most of the benefits and drawbacks of the previous section, except you need to truncate everything in the database, because you don't know what test ran before this one.

Maybe: Run all tests in their own transaction, then roll it back

The idea here is that you start a transaction in your test suite, then you run the application code, then you invoke a ROLLBACK in the test suite, restoring the database to its pristine state. The application code needs a pointer to the transaction, so the objects it creates exist inside of that.

Conceptually, there's nothing wrong with this method, but if you have any application code that starts a transaction, you will get in trouble with Postgres and MySQL, and you may not have a great time with other database flavors. In theory, you could make BEGIN and COMMIT a no-op in application code called from tests, but you are adding a lot of complexity there and the cost starts to outweigh the benefit.

Do: Avoid truncating the database at all

If each test is creating objects that it needs, and those objects don't conflict with anything else, you basically don't need to truncate the database ever. Sure you can add a command to clean it out if it gets too unwieldy, but you don't need to automatically do it between test runs.

This method is very consistent - tests behave the same way every time, they write the objects they need to the database. It also allows you to run all of your tests in parallel.

This requires a small change to the way you write tests - you can't make any assertions about the total number of objects in a given table, for example. If you want to test upserts by trying to write two records and then running SELECT COUNT(1) FROM table and ensuring only one record exists, that will fail because all of your tests are going to be writing to that table simultaneously. Instead, check for the number of records scoped to an account that's created for that test, or similar.

Maybe: Run each test in its own schema

Before running each test, copy the schema from a 'default' schema, and then run the test against the new schema. When the test completes, drop the schema. There's an example function to clone schema available on the Postgres wiki.

This is certainly a technique that provides you full isolation for each test, which allows you to run tests in parallel and ensure each test has a clean database. However, you have to pay the schema clone cost for each test, plus you have to create a new connection for each test. In my experiments on a 2.5 GHz core i7 Macbook Pro, cloning the database schema took about 200ms, and cloning the entire database took about 400ms. To me, these are too high of startup costs to pay to run a single test.

You could imagine having a background job with the sole purpose of creating enough schemas that you don't have to incur the 200ms latency when you actually run the tests - you could just find one of the already created schemas, though you'd need to wipe created schemas when you ran a migration, and that's getting pretty complex.

Assorted notes

  • If each test is creating the objects it needs, and tests don't rely on a clean database state, then you should be able to invoke t.Parallel() at the top of each database test. t.Parallel() will truly try to run each test in parallel, so you may have too much parallelism, but that's a better problem to have than too little. Experiment with the number of connections you have open to the database (or add benchmarks) to find a number that makes the most sense.

  • Prepared queries run about 30-40% faster than normal (fast) unprepared queries, because you don't have to pay the overhead of parsing the query statement. The Go *sql.DB object is thread safe, so you want to reuse it across all of your tests, instead of creating a new one in each test and paying the overhead to establish a connection to the database.

    A library like sqlc will help make it easy for you to get prepared queries.

Thanks to Phips Peter, Kyle Conroy, Alan Shreve, and David Strauß for reviewing drafts of this post.

Liked what you read? I am available for hire.

How to Force a Recall Election for the SF School Board

It is difficult for children, especially young children, to learn over Zoom. It is more difficult to teach critical skills like learning to read and write over Zoom. As Heather Knight and others have noted, keeping children isolated has severe impacts on their mental health.

It is the Mayor's top priority to get children back in schools. It is inexcusable that the San Francisco School District Board has not gotten children back in schools. The children who are most harmed by this failure are low income children in the Southeastern neighborhoods. Every single candidate for School Board last fall highlighted the importance of equity but has been unwilling to do what it takes to reduce inequality on this issue, the biggest one they will face while elected - get children back in schools so they can learn to read.

Even if you are not a parent, you should be interested in this issue. Who is going to want to move to San Francisco if the school system is not interested in educating students? If I had school age kids I would be looking for anything to get my kids back in school and doing things that are normal for kids to do. Keeping kids at home is not good for the community.

There are seven members on the SFUSD School Board. Four Board members were just elected in November and cannot be recalled until May 3, 2021. The other three can be recalled immediately. To force a recall election, you need to collect the signatures of 10% of the city's voters, around 51,000 votes.

Every recall election has signatures thrown out because they are signed by people who aren't residents or signatures or addresses don't match. So you probably need to collect twice as many signatures - around 95,000 signatures. There are about 515,000 voters in San Francisco, and around 100,000 parents of students in the SFUSD school system.

You can either get volunteers to collect signatures door to door or pay signature collectors about $8 to $15 per signature, or a mix of both. So you are looking at around $76,000 to $1,400,000 for a fully professional recall campaign. I can get you in touch with people who can collect signatures.

That said, you may not need to collect all the signatures. The goal is to put political pressure on the Board. The threat of a recall election was enough to get Gavin Newsom to change his behavior, and it may be enough here as well.

Liked what you read? I am available for hire.

Decline the 15 Minute Post-Vaccination Waiting Period

In very rare cases, the Pfizer and Moderna vaccines will cause the person being vaccinated to have an allergic reaction. When I say very rare, I mean it; the chances are a few in a million, or about the same of picking a specific resident of Newark, New Jersey at random out of the phone book.

Because of this chance, the pharmacy/hospital/vaccination site will ask you to wait around for 15 minutes after getting the shot so they can check whether you have an allergic reaction. Most places (scroll through the list on Vaccinate CA) administering the shot are doing so indoors in windowless rooms. People - right now, seniors and others with high exposure to COVID - are being asked to wait for 15 minutes in crowded waiting rooms.

However - waiting in a cramped room indoors is exactly how COVID spreads! Sure, most people are probably wearing masks. But the new B.117 variant is more dangerous and, anecdotally, can get past a cloth mask much more easily. Right after getting the vaccine, but before it has kicked in, we are asking people to huddle in basically the ideal location for transmitting COVID, all to avoid a miniscule risk of an allergic reaction. Not only is this extremely dangerous but it's a huge waste of vaccine - if we know you are going to get COVID today, we shouldn't give you protection against COVID starting a week from now.

The risk of not spotting someone who has an allergic reaction must be weighed against the risk of transmitting COVID. Right now about 3% of the US population is infected with COVID. So about 1 in every 30 people in a vaccination waiting room (likely higher due to selection effects) will be infected with COVID and transmit it to others. About 1-2% of people who get COVID will die from it and more will be hospitalized. Contrast this with about a 1 in ~180,000 risk of an allergic reaction. It's just not comparable.

If you are offered the vaccine, and the waiting area is indoors, I would urge you to decline to wait. Explain that waiting indoors with other unvaccinated1 people is not safe, and then wait outside. You can call someone on the phone for 15 minutes who can monitor you for side effects. Or, walk back in after 15 minutes, tell the pharmacist you are OK, and then leave.

You are not breaking the law by doing this and you are aware of the risks. The more people that choose to do this, the more pressure we can put on vaccinators and public health agencies to end this dangerous practice, and offer waiting areas that are well spaced outdoors.

So many people are dying every day and a vaccine is so close now that small changes will have a huge impact on the total number of people hospitalized and dead. Please share this post with someone you know who is getting vaccinated soon.

Thanks to Michael Story for bringing this issue up.

1. The vaccine takes a week to kick in so for all intents and purposes you are still unvaccinated minutes after you have received the shot.

Liked what you read? I am available for hire.

How to Get a Human Operator on the California EDD Paid Family Leave line

Edit: If you are in a desperate situation, or getting rejected multiple days, please call your State Assemblymember. Staffers in the Legislature have access to additional resources and can help you get the assistance you need from EDD.

The California EDD Paid Family Leave phone tree is like a choose your own adventure book, where almost every option leaves you with no option to contact a human. This can be frustrating. But you can reach a human if you know the right buttons to press!

Here is how to reach a human:

  • Call the EDD Paid Family Leave number at 877-238-4373.

  • Press '1' for "benefit information."

  • Follow the prompts to enter your SSN, zip code, date of birth, and weekly benefit amount.

  • The computer will read you an automated list of information about your claim.

The computer will then read a list of prompts. Wait!! After the computer asks if you want to go back to the main menu it will say "press 0 to speak to a human." Press 0 and then wait and you should get a human!

Liked what you read? I am available for hire.

To Predict If You’ll Like a Beer, Look at the Hops

Generally if you name a food or drink, people know whether they like it or not. It is rare for someone to drink a merlot, or try pizza from a new restaurant — toasted bread, melted cheese, tomato sauce and toppings - and be wildly surprised at their reaction to the taste.

I can't quite figure that out for pale ales though. Some pale ales and IPA's had flavors I really liked, and some had flavors I really disliked. I had a tough time predicting which ones I would like and not like.

I had some suspicions - I didn't think I liked beers with much higher ABV than normal or beers that had citrus in them. But I also liked some beers with high ABV and one of my favorite "everyone has it" beers - Sierra Nevada - describes itself as "pine and citrus," so that wasn't quite right.

Anyway, I decided to be somewhat rigorous about this and order a few different types of beers from the bottle shop, and then figure out what I liked or didn't like about them. It turns out the key is the hops - there are some hop varieties (Cascade, Chinook, Noble) that I like a lot, and other hop varieties (Citra, Galaxy, Enigma, others) that I don't at all. If the hop description mentions passion fruit, I probably won't like it. Other than that, I can keep lists.

This is both satisfying - I can predict which beers I will like and not like, now — and frustrating. Why is this so difficult for consumers to figure out? Why does the category definition of "pale ale" include so much stuff? Like imagine if you ordered a "cheese pizza", and sometimes it would come with anchovies and sometimes with pineapple, and sometimes with nothing. People would demand better words to describe the differences between the things.

If you have ideas or answers, I would love to hear from you.

Liked what you read? I am available for hire.

Using a Bernzomatic TS8000 Kitchen Torch to Sear Meat

For a company trying to sell and explain a product, a lot of this information was amazingly difficult to find so I wrote this.

For the rest of this we'll assume you're cooking a steak but the same advice applies to most other meats/cuts.

Why Do You Want A Torch to Sear Meat

To get a good texture on a steak, you need to get the outside of the steak really hot. If you keep the steak on the heat source for too long, though, it will start to cook the inside too much, and you'll end up with a well done steak.

A torch helps with this problem by making it possible to sear the outside of the steak very quickly which means the outside can get a nice sear while the inside stays at medium rare.

What to Get

You want a torch that can char the surface of a steak in under a minute. Most of the torches can't actually get that hot!

I used a butane crème brûlée torch for years and would get frustrated my steaks didn't look like the ones on Serious Eats, unless I torched them for 5-6 minutes. The torch wasn't hot enough. Using a cast iron pan by itself, even on the highest setting is also not likely to get hot enough. If your steak does not look as black as the one in Serious Eats the outside is not getting hot enough.

I read the Wirecutter guide and got the Bernzomatic TS8000. This torch is definitely hot enough; with propane it's about 3x as hot as my crème brûlée torch. I used it tonight to sear a tri tip. It is so much better.

Is that it? (No, you need fuel)

No. The Bernzomatic torch is just a torch; you still need to buy fuel. The TS8000 works with either butane or propane. You don't want butane though, you want propane, because it gets 50% hotter than butane does.

Every photo on the Internet of both the TS8000 and propane fuel tanks either shows them connected or with the caps on. You need a propane tank that can connect to this, on the bottom of the TS8000.

The top of your propane canister should look like this, with the cap off:

Bernzomatic sells a compatible 14 oz propane tank. You can also use the green Coleman camping gas tanks. The advantage of the Coleman tank is it is cheap and your grocery/hardware store probably has them. It weighs 16 ounces full, which sounds heavy but, it's fine, it's what I used.

I tried to find a small tank - 5-10 ounces - but didn't find anything promising. You'll probably get something in the 12-16 ounce range. Just put it on the end of the torch and sear with the whole tank on the end of the torch.

Summary

  • Get the Bernzomatic TS8000, it is one of the few torches that gets hot enough

  • Use propane, not butane, with it

  • Coleman camping gas tanks are fine

That's it. Here is the manual for the TS8000. Happy searing!

Liked what you read? I am available for hire.