I started figure skating when I was 4 or 5. It was my Mom's idea. She wanted something of her own to do with the kids.
The first thing you learn when you're taking skating lessons is how to fall. My sister would even stick a pillow in the back of her pants to cushion herself.
Nothing cushioned the fall she took on her chin. Blood on the ice. Stitches.
Almost two years ago I went through Y Combinator a second time (S2011). We built some pretty cool technology to help companies brand their own versions of popular games. Games like Bejeweled. Imagine if a company like The Gap let you play their version of Bejeweled, but instead of jewels they were Gap logos, and pictures of models wearing the latest shirts, and you could even win a prize.
We had people playing an average of two hours a day. I was pretty damn excited and hopeful.
But we weren't getting enough repeat business. The product remained in experimental marketing budgets and never got any serious traction. It also wasn't something I would personally use every day. The product didn't have my soul.
We shuttered the work. It was a very, very hard fall. This time on my chin.
The other day I was sitting with a friend, getting pizza and talking about children. He told me he and his wife play a game with their toddler son: they act like buffoons.
They make fools of themselves and fall around on the ground. The kid loves it. He said his son has started mimicking them. This little toddler will act like a buffoon himself, fall, and then look over at his parents to see their reaction, expecting smiles.
It sounded very cute.
But what struck me though was the lesson my friend was teaching his son. It's OK to act like a goofball. Not everything needs to be bottled up and perfect. It's OK to fall. It doesn't hurt that bad. It can be funny too.
You probably wouldn't be surprised to know my buddy is an entrepreneur. He's taken his share of falls.
I was figure skating pretty frequently up until about the age of 16. When you skate that long, you're doing an incredible amount of jumping and falling. Mostly falling. There's even an apparatus you start using with your coach: they can hold you up in a harness while you attempt to jump so that you don't fall. You use that a fraction of the time when you're practicing. The rest of time, you spend picking up new bruises and feeling cold from the ice. You're lucky if the Zamboni didn't just resurface the ice. Because then you're wet and cold.
But you keep jumping. And you keep falling.
Sometimes it took months. Sometimes there was blood. More often there were bruises. But every time I fell ice-skating, I was trying to accomplish a jump I eventually figured out.
My sister still skated for a decade after those stitches.
After shuttering the branded games we were doing at Cityposh, I was stuck in a dark place groping for ideas. That's what entrepreneurs do. I know that. But it doesn't help the loneliness and sense of failure you feel.
I played with a couple things, nothing worked. And then I got an offer to help the tech team at the Obama re-election campaign. It was a great break. Not relaxing on most levels. But a break from the groping nonetheless. A break to let me get up off the ice and let my bruises heal.
I have no idea how it's going to turn out. What I am sure about is that I'm going to fall again. It's going to hurt. It's going to bruise. There's probably going to be blood.
But that's what we do. We try. We play. We act like buffoons. Because it's fun. It doesn't hurt that long. Not when you realize you're surrounded by people supporting you – all they want is to see you enjoy yourself. They don't care if you fall. They just want to see that smile as you try.
P.S. You might enjoy following me on Twitter: here.
Being good developers and designers, we typically define reusable features like a navigation bar or a footer and include them in multiple pages of our design. In PHP we might use “includes”. In a web application framework like Ruby on Rails, we have our “layouts” and our “partials”. But too often, we prematurely reach for those tools.
Having a layout saves me a lot of time. Especially if I have to refactor something. Imagine having a navigation bar on each page but then needing to add another link in it. If the navigation wasn't in some kind of resuable layout, I'd be opening up dozens of files just to edit the same thing over and over.
Saving time is great for me, but is that optimization actually solving a problem my customer has?
Maybe a user is in the middle of a task, struggling to write a very important document. Do they really need to be able to logoff from this page right now? At this moment, do they care what's on your blog? Are they going to need that single click to get to their password change form?
It surprised me a bit how little “consistency” Svbtle, the blog network where I'm writing this essay, has on different pages.
Featured stories page - completely it's own design.
Unpublished posts page - completely it's own design.
Editing a post - completely it's own design.
Applying to write on Svbtle - you get the idea.
Similar color and typography choices being shared, but when you edit your first blog post, it takes a few seconds to reorientate yourself. How do I get back to the blog post list? Oh, there's where I click.
But it makes a lot of sense.
Dustin, Svbtle's designer, has figured out his users have a lot of different tasks to do. Some people are just blog readers and need to be able to find something consistently, read it in 5 minutes and bounce. But someone, trying to find all the latest Svbtle posts, has another task. And someone, writing their latest essay, has a completely different job at hand.
There's quite a few tasks writers have: saving drafts, getting feedback, editing, etc. As I tackled making some of these jobs easier, I found myself doing what I often do, having a new page inherit from a layout so I don't have to reinvent the wheel.
And I got stuck. I struggled to figure out a good way to help a user look over their old drafts, or have room to merge in an editor's changes.
My mind wandered back to what Dustin is doing here with Svbtle's design. He seems to almost start from scratch on each job his user has. I tried that.
How would this page look, if I had the entire screen again at my disposal? If you're a Rails developer you might do something like this:
def index
@document = current_or_guest_user.documents.find(params[:document_id])
render action: 'index', layout: false
end
On new pages I create, I set my layouts to false. This forces me to create an entirely new HTML page for that task. I don't reuse the navigation or the footer or anything else. I don't automatically bring over those previous decisions and assumptions I've made to solve the problem at hand.
What's happened is that I find myself free to make decisions purely based on solving my user's problem, not trying to shoehorn my solution into the pixels of space my previous layout had allotted me. By starting a task over from scratch, I've been able to do some pretty neat things that didn't occur to me before. I have an entire canvas again, and really great solutions have presented themselves making my users pretty happy.
Of course, as I complete designing a task a user has, I find patterns that are shared with other tasks and I begin pulling out reusable pieces. But the order in which I now do this is changing and often the opposite of what many of us do with our tools.
Optimize for your efficiency AFTER you've solved a problem a user actually has.
I could look at user retention. Once people start using Draft, do they come back to use it again?
There's some great software to help study how users return to your product. They use a method called cohort analysis, which breaks up users into groups of people who “activate” or sign-up at the same time and then you track their progress as a group. Do users that signup in January after one month use your app more than those users who signed up in December after their first month? They do? Awesome, those features and things you did in February might be onto something.
To use these analytics tools, I have to integrate my application with them. I have to figure out how to send even more data to them.
But I don't want to integrate something else right now. I already have data. It's coming out of my ears. A database full of it. Log files upon log files. Can't some of the data I already have power this user retention analysis? Do I really have to start all over again collecting new data?
I don't want to work harder for more data right now. I want the data to work harder for me.
I got irritated, so I built a simple way to study your Rails app's user retention using a cohort analysis with the data you already have in your database. It's called CohortMe.
To get a cohort analysis, just use this in your Rails app:
CohortMe.analyze(activation_class: Document)
That's it.
Above is an example of studying user retention for Draft. Users are “activated” once they create their first Document. Then they “return” if they create another Document.
During the week starting on 21 Jan 2013, I had 15 people signup. One week later, I only had 1 user still creating Documents. Yuck. That's a terrible retention rate. I better explore why they aren't coming back. Note: it's just bogus test data.
:period - Default is “weeks”. Can also be “months” or “days”.
:activation_class - The Rails model class that CohortMe will query to find activated users. For example: User. CohortMe will look for a created_at timestamp in this table.
:activation_user_id - Default is “user_id”. Most Rails models are owned by a User through a “user_id”. If it's something else like “owner_id”, you can override that here.
:activation_conditions - If you need anything fancy to find activated users. For example, if your acivation_class is Document (meaning find activated Users who have created their first Document) you could pass in: :activation_conditions => [“(content IS NOT NULL && content != '')], which means: Find activated Users who have create their first Document that has non-empty content.
:activity_class - Default is the same class used as the activation_class. However, is there a different Class representing an Event the user creates in your database when they revisit your application? Do you expect users to create a new Message each week? Or a new Friend?
:activity_user_id - Defaults to "user_id”.
Examples
First, figure out who your activated users are. Are they simply Users in your database? Could be. But I prefer treating an active user as someone who has signed up AND done a key feature.
For example, if you created a group messaging app, it's probably a User when they created their first Group.
Next, figure out what a user does to be classified as “returning”. This needs to be another record in your database. Is it a Message they made this week? A Share? A new Document?
For my group messaging tool, my cohort analysis might look like this:
CohortMe will look at Groups to find activated users: people who created their first Group. Next, CohortMe will look to the Message model to find out when those users have returned to my app to create that Message activity.
This assumes a Group belongs to a user through an attribute called “user_id”. But if the attribute is “owner_id” on a Group, that's fine, you can do:
Here's an example from Draft. It's slightly more complicated because I have guest users, and documents that can be blank from people kicking the tires. I don't want to count those. My cohort analysis looks like this:
non_guests = User.where("encrypted_password IS NOT NULL AND encrypted_password != ''").all
@period = "weeks"
activation_conditions = ["(content IS NOT NULL && content != '') and user_id IN (?)", non_guests]
@cohorts = CohortMe.analyze(period: @period,
activation_class: Document,
activation_conditions: activation_conditions)
If you look closely at that table image, you'll notice that the numbers are links. I've tweaked the table in my own app to be able to show me who exactly are those users returning to Draft. You can do the same:
One constant I've recognized in my writing is how much feedback I like to have. I'll write an email, and I'll send a draft to a colleague to see if it's right. I'll write an application to something, and get feedback from friends to see if it makes sense. I'll write a blog post, and send it to my wife.
But being a solo entrepreneur and working alone at home, I often find myself stuck, not being able to get a friend to look at my work.
My wife can only take so much.
At the same time, I've gotten hooked on how simple it is to order a cab on Uber. Click a button, and a bunch of steps happen I don't need to worry about.
So now, Draft, the version control for writing tool I'm making, has a magic “Share with an Editor” button. One click, and you can send whatever you're working on (Christmas letter, cold email to a potential customer, blog post, etc.) to a staff of folks who can review your writing and suggest edits.
What is extra awesome, is that Draft makes it easy to ignore or merge in their changes. Do what you want with them.
Just yesterday I had this blog post edited as well as a customer development type email I was sending to someone. I got a bunch of great edits back. Some I ignored. Most I merged into my work.
Behind the scenes, we're using our friends at MobileWorks to supply the service. They have a college educated crew working 24/7 under a strict NDA. They're a great group who can look over your work, and it's super cheap. (If you need a Virtual Assistant for other services, check out their new product Premier.)
I'm slowly sending beta invites to people that want to give Draft a good trial before I release it to the public. Thank you so much, everyone, for all the feedback. It's definitely helping me make a better product.
It's awesome: I love the simplicity combined with power of markdown.
It's tough to get people to open your mail. Snail or digital.
A few years ago I blogged about a restaurant in my neighborhood that sends out these crazy handwritten pieces of mail. Not just the letter itself, but the entire envelope is covered in handwriting about my birthday. It's impossible not to open up that type of letter :)
I recently noticed a new trend around this time of year. Making a piece of mail look like it's been sent from the taxman.
Good old Form 854-A, in bold print. This must be something important I need for my taxes this year?
Opening it up.
Nope. It's just a renewal form for a magazine subscription.
I wanted to show off a preview of what I've been working on. It's a better version control system for writing. I call it Draft.
As a writer, I've been very annoyed at my options for version control. Software like iCloud and Google Docs end up saving a lot of arbitrary junk making it very hard to find an old draft that has that certain paragraph I ended up deleting and now want back.
And when I share a Google Doc with someone to help edit it, they overwrite my master copy making it insanely difficult to accept individual changes they've made.
A lot of folks try to end up learning Git, which is a popular version control system used by software developers. It really is a great tool if you're in software development. But even as a developer it's full of headaches. Writers don't need all this added complexity and overhead to manage versions of their work.
Draft solves this. Draft is a distraction free editor that auto-saves as you type. But as you go along, you can mark major versions of your work:
When you share your document, any changes your collaborator makes are on their own copy of the document, and you get to accept or ignore each individual change they make. Here's what that looks like:
Draft will be released to the public very soon.
But I'm gradually sending the sign up link to friends, family and folks that want to give it a good trial right now. I've been insanely flattered and motivated by the feedback.
The website is one of the most beautiful I've seen in a long time.
Bijan
If you'd like to try it out early just add your email to the form below.
I bought a sub the other day at the sandwich chain Jimmy John's, and I noticed something very innovative about their loyalty program when they gave me a punch card.
Sure they gave me the typical buy 10 subs, get one free card. But there was just one twist…
9 of the slots on the card were already punched.
Usually a loyalty program at a retail store like this is a punch card with 10 “slots” on it. Every time I buy something the cashier punches another slot. And once I collect 10 punches I get a free something.
The premise of punch cards like this is to play on a commonly used “game mechanic”. Humans like to collect things. We like to finish things. If we know we have something that's incomplete, it nags on us until it's accomplished.
“Hmm, I shouldn't go to McDonald's today. I only have 3 more lunches to buy and I'll get my free one,” someone hopes his customers are saying.
But I've got dozens of these cards from all over the place just collecting in a junk box. Everything has 1 or 2 punches on it. They don't seem to be making me very loyal to anything do they?
See, one problem with this program is that if that percentage to complete a loyalty punch card seems too high, I'll quickly abandon the effort.
I've seen this play out many times creating Inkling and Cityposh, projects that rely heavily on game mechanics working well, and is a common worry for game developers.
It's no fun to play a game when winning something looks so far out of reach.
Such as getting on a leaderboard. We try to make sure leaderboards aren't filled with early bird users who've simply accumulated points and have reached levels that newcomers have zero chance of reaching.
And so, that's one of the feelings that pops up when playing these loyalty games at stores.
I have so many options for lunch. If I've got a single slot punched on some loyalty card and need 9 more to go, that seems like a long game to play to get my free prize. I'd rather just keep getting some diversity and go to one of another 100 places near me.
So the folks at this particular Jimmy John's did something genius. They gave me a chance at an early win: “buy just one more sandwich and already get one free”.
But they disguised it as an even bigger accomplishment. I've completed 9 things already without even trying! Just one more visit to the store and I've already won the game.
It definitely got my loyalty and I bought my “10th” sub the next day.
This is a great reminder to folks hoping to use game mechanics to encourage users to stay loyal to their business: have smaller wins, and disguise them as big wins.
It's ok to have a large prize or accomplishment after doing a bunch of work, but don't forget to offer some kind of reward at an early level in your 'game'. Give customers an immediate sense of accomplishment. That's why you'll see most games have a very early win that comes with a bunch of celebration. “Yay, you signed up for the game. Here's a badge! And some points! And lots of noise and whistles.”
This whole experience also helps remind us: don't cargo cult “game mechanics” and hope for the best.
There's quite a bit of psychology in developing games, and a single “mechanic” can have a lot of consequences. Someone might hear about leaderboards and use one for their business, but then not realize the psychology behind a leaderboard. They'll often create a disincentive to newcomers from even starting the game at all.
P.S. You should get my next post on Twitter: here.
We once went into a meeting with someone who had gotten hold of some market research data from Ocean Spray. She said that they had tested guava as a flavor and decided that the name evoked negative images for people. We looked at each other and said, 'OK, we're making it.' Now it's one of our top sellers.
Tom Scott shares a great piece of wisdom on where to find new ideas. Start looking for stuff that the mainstream doesn't like. You can find a gold mine.
Look at things like hot sauce. Oysters. Malört.
That's what most people look like drinking Malört.
Me? I love the stuff. We drank a bunch of Malört at the Obama campaign. Most did it just to say they tried such a terrible thing once in their life. But a couple of us did it because we love bitter drinks. (There's another great bitter liqueur, Cynar. I like shaking some of that up with an entire raw egg. It's delicious.)
That's how many things are. There's some things people really don't like. But then you'll find some super fans of that same thing.
Study mainstream America. Observe mainstream marketing. Then think about the exact opposite.
Look at extroverts. Facebook has tapped into the fact that the mainstream likes to share every god damn piece of their lives with the entire world. Most people are extroverts or at least try very hard to emulate extroverts.
Introverts are very underserved.
There's a company I like to follow, Pinboard, whose founder, Maciej Cegłowski, realized this. So he created a bookmarking application that's got great privacy controls. He's doing very well. Their motto?
Social Bookmarking for Introverts
Look at my last blog post. It was a little different than previous posts. I made it super long, brought up a few different theses instead of a single point, and asked a controversial question I didn't answer directly. What happened?
Some folks hated it. I couldn't believe some of the vitriol and snarkiness I got in comments related to it.
But the funny part was, much more than usual, I got emails, and comments from friends telling me how much they enjoyed it. How much it inspired them. I was very surprised.
I didn't even know some of these friends even read my blog.
But for some reason this piece of prose of mine that somehow made some people pissed or uncomfortable, provoked others to reach out and mention how much they liked it.
Try to make something everyone likes, and you'll end up with something no one does.
So, need a new business idea? Look at mainstream tastes. What does everyone typically like. Then think about the exact opposite. Those folks are very underserved. You'll probably be able to find at least 1,000 super fans. Make them happy. You'll have customers for life.
P.S. You should get my next post on Twitter: here.
Immature poets imitate; mature poets steal; bad poets deface what they take, and good poets make it into something better, or at least something different.
T.S. Elliot
A bunch of folks have been asking for my reaction to 37signal's recent product launch of Basecamp Breeze, a tool for creating a group email address like groupname[at]breeze123.com. A few years ago I created a tool very similar in spirit called Tgethr. You can easily create a groupname[at]tgethr.com.
I've even gotten condolences about 37signals copying my idea. :)
So I thought this would be a good opportunity to write a few thoughts on competition and copying ideas, especially since this is a real common area where people get stuck.
First of all, I highly doubt I was even in 37signal's peripheral vision as they were planning Breeze. Even if they did get inspired by Tgethr, I'd be flattered.
If my idea isn't worth copying then it's not a very good idea. If my product or business can't handle a new competitor, then it's not a very good product.
A successful entrepreneur has to be comfortable being surrounded by competition. Not just surrounded. Swimming in it. Drowning in it.
Inkling, my first company of any success, got started because of all sorts of borrowing of ideas.
A bunch of years ago, a friend of mine asked if I'd heard of prediction markets. He mentioned some innovative companies using virtual stock exchange like things for ideas. Sounded kind of cool.
A couple years later I was walking through an airport bookstore and happened upon a best seller rack promoting Wisdom of Crowds by James Surowiecki. I tore through that book and was sold on this concept of crowd wisdom. I really wanted to try out prediction markets for myself.
I went to Newsfutures.com, the prediction markets company heavily mentioned in the book, to see if I could play with their product. No. I'd have to work with a salesperson. I found a second company. Another salesperson.
I decided I wanted to craft my own prediction market software. So I got some folks to build a company with me.
Of course, we have what feels like insane competition. If you Googled prediction markets then, you'd get Newsfutures followed by all sorts of other companies and projects. Even free open source stuff.
You'd go to the Newsfutures site and see dozens of client logos and testimonials. There's Surowiecki's New York Times best selling book bringing all the attention to Newsfutures.
Did I mention yet Newsfutures had a 5 year head start on us?
What do we have?
Very little.
We convinced Y Combinator, a new seed investment partnership, to take a chance on us in the second batch of the program. We got $18,000 from them which was gone in a snap supporting 3 people paying rent in Silicon Valley (and mortgages in Chicago).
No clients or relationships to turn into clients.
Zero competitive advantage.
Not to mention, as soon as we launched the first version of our product, which we'd been working on for a couple months, another competitor launches.
They've got a neat name, CrowdIQ. Their stuff looked super polished. They'd been working on it for a year. They even seemed to understand prediction markets much more than any of us did. I didn't have a clue what a “market scoring rule” was or how to interpret these crazy ass academic papers from the Godfather of prediction markets, Robin Hanson.
Most people would have stopped at our first problem. Come up with an idea, Google it, and realize there's already a dozen companies working to solve XYZ. Moan a bit about not having any luck and go back to watching TV.
But we did have something going for us.
We're probably what Paul Graham would refer to as cockroaches. We just wouldn't die.
For better or worse, I hate giving up.
In grade school, I broke my wrist playing basketball. After a bit of fetal position on the ground, my father, the coach, put me back in the game. I just dribbled with the other hand. They finally forced me out of the game, when someone elbowed me in the face and my nose wouldn't stop bleeding.
A few years ago, someone fell on top of me in a martial arts class. His elbow went into my ribs. We both heard a noise. I was pretty sure I broke something. Painfully told myself (and my wife) I was fine, and went to a wrestling practice two days later. After that second practice, I was pretty convinced I had broken a rib when I couldn't physically take off my shirt in the locker room and was having trouble breathing. Finally the Emergency Room doctor gave me the same diagnosis after x-rays.
I like challenges too much and don't like quitting. Often things are painful for just a moment and go away.
So we kept at this prediction markets game. For years. Trying shit loads of angles and ideas.
Soon CrowdIQ disappeared. Later Newsfutures became irrelevant.
You'll now find Inkling at the top of the results for prediction markets in Google.
Of course we picked up new competition. So the cycle goes.
Then there's Tgethr. Even it was borrowed.
A few years ago, I realized coincidentally enough, I wanted something simpler than 37signals' own product, Basecamp, to organize communication within Inkling as well as a few groups of family and friends. Immediately I thought of Google Groups, but it was a shithole.
I stumbled on FamSpam, a new company from Chris Wanstrath and PJ Hyett that was fairly useful for the job. But they started shutting it down (to create the super successful Github, so they made out ok). I still wanted that simple collaboration tool. So I borrowed the idea and created my own: Tgethr.
I don't have any secrets here about defeating your competition. There's some great advice from folks like Clayton Christensen and Youngme Moon.
What I do know is that competition isn't a show stopper. It can't be. You'll face oodles of it. Forever.
And Tgethr remains an incredibly useful tool for me and others. It's better than a group email address. It's got a secure web archive that merges group conversations together. It can send encrypted messages. It auto formats things like image links and blocks of code for developers. It has hooks to other services like Pivotal Tracker and Dropbox. All in a very simple package.
So I know Tgethr will keep going. I'll keep going. I'll keep borrowing good ideas and making them my own. And most of all, I'll keep persisting.
You'll have to drag me out of this game bloody and broken.
Using a new gem I created, I was able to optimize a Rails action by 78% (152 ms to 34 ms). The gem takes advantage of Rail's read_multi method to retrieve cached partials in parallel instead of the traditional route of sequentially fetching things from Memcached.
Syntax
Using this gem, if you want to automatically render a collection and cache each partial with its default cache key:
One of the applications I worked on at the Obama campaign was Dashboard, a virtual field office we created. Dashboard doesn't talk directly to a database. It only speaks to a rest API called Narwhal. You can imagine the performance obstacles we faced building an application this way. So we had to take insane advantage of caching everything we could. This included looking for as many places as possible where we could fetch from Memcached in parallel using Rails' read_multi:
read_multi(*names) public
Read multiple values at once from the cache. Options can be passed in the last argument.
Some cache implementation may optimize this method.
Returns a hash mapping the names provided to the values found.
The result of all this is I'm constantly on the lookout for more places where caching can be optimized. And one area I've noticed recently is how us Rails developers render and cache collections of partials.
For example, at Inkling we render a client homepage as a collection of divs:
And each _market.html.erb partial is cached. If you looked inside you'd see something like:
<% cache(market) do %>
slow things....
<% end %>
It's tough to cache the entire collection of these partials in a single parent, because each user sees a different homepage depending on their permissions. But even if we could cache the entire page for lots of users, that parent cache would be invalidated each time one of its children changes, which they do, frequently.
So for a long time I've dealt with the performance of rendering out pages where we read from Memcached dozens and dozens of times, sequentially. Memcached is fast, but fetching from Memcached like this can add up, especially over a cloud like Heroku.
Luckily, Memcached supports reading a bunch of things at one time. So I've tweaked the render method of Rails to utilize fetching multiple things at once.
How much faster?
Depends on how many things you're fetching from Memcached for a single page. But I tested with a simple application that renders 50 items to a page. Each of those items is a rendered partial that gets cached to Memcached.
There's two actions: without_gem and with_gem. without_gem performs caching around each individual fragment as it's rendered sequentially. with_gem uses the new ability this gem gives to the render partial method.
Using Blitz.io I ran a test ramping up to 25 simultaneous users against the test app hosted on Heroku. I configured Heroku to use 10 dynos and unicorn with 3 workers on each dyno.
without_gem
This rush generated 648 successful hits in 1.0 min and we transferred 24.49 MB of data in and out of your app. The average hit rate of 10/second translates to about 892,683 hits/day.
The average response time was 168 ms.
You've got bigger problems, though: 1.07% of the users during this rush experienced timeouts or errors!
with_gem
This rush generated 705 successful hits in 1.0 min and we transferred 24.08 MB of data in and out of your app. The average hit rate of 11/second translates to about 969,892 hits/day.
The average response time was 90 ms.
New Relic's report was even more rosy. According to New Relic, the test action went from an average of 152 ms to 34 ms.
Installation
Add gem 'multi_fetch_fragments' to your Gemfile.
Run bundle install.
Restart your server
Render collection of objects with their partial using the new syntax (see above):
Note: You may need to refactor any partials that contain cache blocks. For example if you have an _item.html.erb partial with a cache block inside caching the item, you can remove the method call to “cache” and rely on the new render method abilities.