Ruby Hero 2016

This year I was lucky enough to be one of 9 rubyists chosen to receive the Ruby Hero award. I'm also only one of 2 Heroes to be pictured wearing a hat this year.

I've been describing the award as "The Oscars" for Ruby programming for those not in the community. This description went over really well, however my Mother-In-Law got a bit confused and asked if I won because I "wore a hat to my talk this year" (i.e. dressed up as Indiana Jones).

Thankfully, the award has nothing to do with my ability to act.

I'm incredibly grateful to be a part of the Ruby community. I started programming Ruby as my first language back in 2006. I thought I would be super rich by making a website and selling it, instead I found something even better. I found an amazing and supportive community. It's impossible to quantify how friendly, and helpful a large group of self-identified people are. If I could, then Ruby would be at my personal number one spot.

There were a few bad apples. In my first programming job interview, a CTO told me "I couldn't program" to my face. I got over it. By pushing past the bad I was able to get to the warm collaborative center of the community. I eventually quit my mechanical engineering job and got a software dev position. I became active with austinonrails.org. I started teaching programming and even taught at the University of Texas once. I've written heavily on tech topics at this blog, and I enjoy staying active in open source.

For the most part I've gotten nothing but encouragement and help. It is so easy to be mean, snarky, or cynical. There is so much negative in the world. It takes a great deal more effort to be productive and helpful.

I was inspired by the idea of nominating a "Ruby Hero" this year to start a personal experiment. I like the idea that people get up and share that they have someone who made an impact in their lives. It's sad that there were 500 or so nominations but only a few got to be recognized. I wanted to show those around me that they're actively making the world a better place. Nothing says "thanks" quite like a hand written card, so I printed off a bunch of postcards:

I intended to hand them out blank for others to write on, but I ended up writing so many myself that I went through my whole stash. I had to go buy some regular cards at a grocery store just to have enough. It felt really good to give out "thanks", and once I started I couldn't stop. Here's an action shot:

I want to keep this up. I'm exploring ways to encourage more people to speak up about the good others have done for them. I've printed out a whole bunch of postcards and I'll be at OSCON May 16-19 in Austin (my home town!), find me and grab one. Then consider someone who made your day, week, or year; and let them know.

Before I get too carried away, I would like to thank Heroku for taking a chance on me over 4 years ago. They also employ another of the 2016 Ruby Hero's, Koichi Sasada, who works on Ruby core. Heroku has a history of supporting the Ruby and the Ruby community. They've supported my interests in speaking and open source. I'm proud to work with such an amazing team.

This past year has been a whirlwind. I had a son, I got into Sprockets Core, and now this award. I sincerely appreciate this honor and I plan to keep contributing. I also see the award as more than recognition. I see it as a challenge. It says to me "strive to be more". It says "go out there knowing that people are watching you now". It says "set an example and live with purpose". While this award is a career and community high for me, I don't see it as the end of my journey. It's a beginning. Thank you all for reading and for making Ruby such an amazing community.

Container-Ready Rails 5

Rails 5 will be the easiest release ever to get running on Heroku. You can get it going in just five lines:

$ rails new myapp -d postgresql
$ cd myapp
$ git init . ; git add . ; git commit -m first
$ heroku create
$ git push heroku master

These five lines (and a view or two) are all you need to get a Rails 5 app working on Heroku — there are no special gems you need to install, or flags you must toggle. Let's take a peek under the hood, and explore the interfaces baked right into Rails 5 that make it easy to deploy your app on any modern container-based platform.

This article originally published on the Heroku Blog.

Production Web Server as the Default

Before Rails 5, the default web server that you get when you run $ rails server is WEBrick, which is the only server that ships with the Ruby standard library. For years now Heroku has recommended against using WEBrick as a production webserver mostly due to performance concerns, since by default WEBrick cannot handle more than one request at a time. With the addition of ActionCable to Rails 5, the Rails team needed a web server that could handle concurrent requests, so they decided to make Puma webserver the new default. Now, when you deploy a Rails 5 app without a Procfile in your project and Heroku boots your application using $ rails server, you'll get a performant, production-ready web server by default.

Note: if you're upgrading an existing Rails app, you'll want to manually add Puma to your app.

In addition to shipping with Puma, Rails also generates config/puma.rb and efforts were made to allow Puma to read this config file when it's booted by the $ rails server command. This feature is baked into Puma 3.x+, which allows Rails to configure Puma around the number of threads being generated.

Active Record will generate a pool of five connections by default. These connections are checked out from the pool for the entire duration of the request, so it's critical that for each concurrent request your webserver can handle, you need that many connections in your connection pool. By default, the Puma server starts with up to 16 threads. This means that it can be processing up to 16 different requests at the same time, but since Active Record is limited to five connections, only five of those requests will have access to the database at a time. This means eventually you'll hit this error:

ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds. The max pool size is currently 5; consider increasing it

The solution was to tell Puma that we only want five threads by default. We also wanted a way to re-configure that count without having to commit a change to git, and redeploy for it to take effect. So by default Rails specifies the same number of threads in Puma as Active Record has in its connection pool:

# config/puma.rb

# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method takes a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum, this matches the default thread size of Active Record.

threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count

Note: For a production service there is little benefit to setting a minimum thread value.

Now when you deploy, your Puma thread count will match your Active Record thread count so you won't get timeout errors. Later the default for Active Record was adjusted to take advantage of the RAILS_MAX_THREADS environment variable. When you scale your Puma thread count via that environment variable, the Active Record connection pool automatically does the right thing.

Port

On Heroku, we recommend you specify how to run your app via the Procfile — if you don't specify a Procfile we will set a default process type for you. Since Heroku apps run inside containers, they need to know which port to connect to, so we set the $PORT environment variable. The buildpack will specify a web process command if you don't provide one. For example, if you're deploying a Rails 2 app without a Procfile, by default your app would run:

$ bundle exec ruby script/server -p $PORT

In Rails 5 you can now use the $PORT environment variable to specify what port you want your app to connect to. This change doesn't really affect how your app runs on Heroku, but if you're trying to run inside of a logic-less build system it can help make it easier to get your application to connect to the right place.

Serving Files by Default

Prior to Rails 4.2, a Rails app would not serve its own assets. It was assumed that you would always deploy behind some other kind of server such as NGINX that would serve your static files for you. This is still the default behavior, however, new apps can have the static file service turned on via an environment variable.

# config/environments/production.rb


config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

Heroku will set this value when you deploy a Ruby app via the Heroku Ruby Buildpack for Rails 4.2+ apps. Previously you would have to either set this value manually or use the rails12factor gem.

STDOUT Logging

The default logging location in Rails has always been to a file with the name of your environment so production logs go to logs/production.log. This works well for a traditional deployment but when deploying to a container-based architecture, it makes retrieving and aggregating logs very difficult. Instead, Heroku has advocated for logging to STDOUT instead and treating your logs as streams. These streams can then be directly consumed, fed into a logging add-on for archival, or even used for structured data aggregation.

The default hasn't changed, but starting in Rails 5, new apps can log to STDOUT via an environment variable

if ENV["RAILS_LOG_TO_STDOUT"].present?
  logger           = ActiveSupport::Logger.new(STDOUT)
  logger.formatter = config.log_formatter
  config.logger = ActiveSupport::TaggedLogging.new(logger)
end

This value can be set by the container or the platform on which your Rails app runs. In our case, the Ruby buildpack detects your Rails version, and if it's Rails 5 or greater will set the RAILS_LOG_TO_STDOUT environment variable.

DATABASE_URL

Support for connection to the database specified in $DATABASE_URL has been around since Rails 3.2, however, there were a large number of bugs and edge cases that weren't completely handled until Rails 4.1. Prior to Rails 4.1, because the DATABASE_URL integration was not 100% of the way there, Heroku used to write over your config/database.yml with a file that parsed the environment variable and returned it back as in YAML format. You can see the contents of the "magic" database.yml file here. The biggest problem is that this magic file replacement wasn't expected. People would add config keys for things like pool which specifies your Active Record connection pool, and it would be silently ignored. So they had to resort to hacks like this code to modify the database configuration

# Hack, do not use with Rails 4.1+

Rails.application.config.after_initialize do
  ActiveRecord::Base.connection_pool.disconnect!

  ActiveSupport.on_load(:active_record) do
    config = ActiveRecord::Base.configurations[Rails.env] ||
                Rails.application.config.database_configuration[Rails.env]
    config['pool']              = ENV['DB_POOL']      || ENV['MAX_THREADS'] || 5
    ActiveRecord::Base.establish_connection(config)
  end
end

Even then, you need to make sure that code gets run correctly in all different ways your app can be booted. For example, if you're preloading your app to take advantage of Copy on Write, you'll need to make sure this code runs in an "after fork" block. While it works around the issue, it normally meant that configuration was spread around an application in many places, and often resulted in different behaviors for different types of dynos.

After the 4.1 patch, Rails merged configuration from the config/database.yml and the $DATABASE_URL environment variable. Heroku no longer needed to over-write your checked-in file, so you can now set pool size directly in your database.yml file. You can see the database connection behavior in Rails 4.1 and beyond explained here.

This allows anyone who does not need to configure a database via an environment variable to run exactly as before, but now anyone connecting using the environment variable can keep additional Active Record config in one canonical location.

SECRETKEYBASE

At around the time that Rails 4.1 introduced $DATABASE_URL support, Rails was introducing the secret token store as a new feature. Prior to this feature, there was one secure string that was used to prevent Cross-site request forgery (CSRF). Lots of developers forgot that it was in their source, and they would check that into their git repository. It's never a good idea to store secrets in source control, and quite a few applications that were public on GitHub were vulnerable as a result. Now with the introduction of the secret key store, we can set this secret token value with an environment variable.

# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Now we do not need to check secure things directly into our application code. With new Rails 4.1+ apps you are required to provide a secret via the SECRET_KEY_BASE environment variable, or to set the value some other way.

When deploying a Rails 4.1+ app, Heroku will specify a SECRET_KEY_BASE on your app by default. It is a good idea to rotate this value periodically. You can see the current value by running

$ heroku run bash
Running bash on issuetriage... up, run.8903
~ $ echo $SECRET_KEY_BASE
abcd12345thisIsAMadeUpSecretKeyBaseforThisArticle

To set a new key you can use

$ heroku config:set SECRET_KEY_BASE=<yournewconfigkeyhere>

Note: That this may mean that people who are submitting a form in the time between the key change will have an invalid request as the CSRF token will have changed.

Safer Database Actions

One of the scariest things you can say to a co-worker is "I dropped the production database". While it doesn't happen often, it's a serious enough case to warrant an extra layer of protection. In Rails 5, the database is now aware of the environment that it is run in and by default destructive actions will be prevented on production database. This means if you are connected to your "production" database and try to run

$ rake db:drop

Or other destructive actions that might delete data from your database you'll get an error.

You are attempting to run a destructive action against your 'production' database
if you are sure you want to continue, run the same command with the environment variable
DISABLE_DATABASE_ENVIRONMENT_CHECK=1

While not required to run on Heroku, it's new in Rails 5, and might save you from a minor catastrophe one day. If you're running on a high enough Postgres plan tier, you'll also have the ability to rollback a database to a specific point in time if anything goes wrong. This is currently available for different durations for all plans Standard and above.

Request IDs

Running a Rails app with high traffic can be demanding, especially when you can't even tell which of your log lines go together with a single Request. For example three requests could look something like this in your logs:

Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:21 +0000
  Rendered welcome/index.html.erb within layouts/application (0.1ms)
Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:22 +0000
Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:23 +0000
  Rendered welcome/index.html.erb within layouts/application (0.1ms)
Processing by WelcomeController#index as HTML
Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)
Processing by WelcomeController#index as HTML
  Rendered welcome/index.html.erb within layouts/application (0.1ms)
Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)
  Processing by WelcomeController#index as HTML
Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)

With Rails 5, the request ID will be logged by default, ensuring each request is tagged with a unique identifier. While they are still interleaved it is possible to figure out which lines belong to which requests. Like:

[c6034478-4026-4ded-9e3c-088c76d056f1] Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:21 +0000
[c6034478-4026-4ded-9e3c-088c76d056f1]  Rendered welcome/index.html.erb within layouts/application (0.1ms)
[abuqw781-5026-6ded-7e2v-788c7md0L6fQ] Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:22 +0000
[acfab2a7-f1b7-4e15-8bf6-cdaa008d102c] Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:23 +0000
[abuqw781-5026-6ded-7e2v-788c7md0L6fQ]  Rendered welcome/index.html.erb within layouts/application (0.1ms)
[c6034478-4026-4ded-9e3c-088c76d056f1] Processing by WelcomeController#index as HTML
[c6034478-4026-4ded-9e3c-088c76d056f1] Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)
[abuqw781-5026-6ded-7e2v-788c7md0L6fQ] Processing by WelcomeController#index as HTML
[abuqw781-5026-6ded-7e2v-788c7md0L6fQ]  Rendered welcome/index.html.erb within layouts/application (0.1ms)
[abuqw781-5026-6ded-7e2v-788c7md0L6fQ] Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)
[acfab2a7-f1b7-4e15-8bf6-cdaa008d102c]  Processing by WelcomeController#index as HTML
[acfab2a7-f1b7-4e15-8bf6-cdaa008d102c] Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)

Now, if you have the logs and you find this unique ID, you can filter to only look at information from that request. So a filtered log output would be very clear:

[c6034478-4026-4ded-9e3c-088c76d056f1] Started GET "/" for 72.48.77.213 at 2016-01-06 20:30:21 +0000
[c6034478-4026-4ded-9e3c-088c76d056f1]  Rendered welcome/index.html.erb within layouts/application (0.1ms)
[c6034478-4026-4ded-9e3c-088c76d056f1] Processing by WelcomeController#index as HTML
[c6034478-4026-4ded-9e3c-088c76d056f1] Completed 200 OK in 5ms (Views: 3.8ms | ActiveRecord: 0.0ms)

In addition to this benefit, the request can be set via the X-Request-ID header so that the same request could be traced between multiple components. For example, a request comes in from the Heroku router which assigns a request id. As the request is processed we can log that id, then when the request is passed on to Rails, the same id is used. That way if a problem is determined to be not caused in Rails, it could be traced back to other components with the same ID. This default was added in PR #22949.

This is another feature that isn't explicitly required to run on Heroku, however, it will make running an application at scale much easier.

Summary

Rails 5 is the easiest to use Rails version on Heroku ever. We also hope that it's the easiest version to run anywhere else. We're happy that the power of "convention over configuration" can be leveraged by container-based deployment platforms to provide a seamless production experience. Many of these features listed such as request IDs and destructive database safeguards are progressive enhancements that will help all app developers regardless of where they deploy or how they run in production. Heroku has been committed to providing the best possible Ruby and Rails experience from its inception, whether that means building out platform features developers need, automating tasks via the buildpack, or working with upstream maintainers. While we want to provide an easy experience, we don't want one that is too "magical". By working together in open source we can make software easier to deploy and manage for all developers, not just Heroku customers.

If you haven't already, try upgrading to Rails 5 beta.

Check out this Dev Center article for more information on getting started with Rails 5.x on Heroku.

Optimist's Guide to Pessimistic Library Versioning

Upgrading software is much harder than it could be. Modern versioning schemes and package managers have the ability to help us upgrade much more than they do today.

Take for example my post on Upgrading to Rails 5 Beta — The Hard Way. Most of the time was spent trying to find all the different libraries my app was using that weren’t compatible yet with Rails 5 and upgrade them.

What if somehow bundle update rails could have known they didn’t work and instead find a version that did work? It turns out that it can, but it requires some pain on the maintainer’s part. In this post, we’ll look at different strategies for declaring dependencies in libraries, why one is dominant right now, and how we might be able to make major version bumps easier into the future.

Keep Reading on Codeship

Get Your Conference Proposal Accepted

Want to speak at a conference? First you'll have to get a proposal accepted. To date, I've helped pick talks for Keep Ruby Weird since it started, and this year I reviewed for RailsConf 2016. I've also written a number of proposals, some that have been accepted, some that haven't.

There's no sure fire formula to guarantee your talks get accepted. In this post I'll share some of the things I liked and disliked while reading proposals as well as some of the things that I've found help when writing my own proposals.

I'll be talking about things I didn't like in proposals, however all examples are made up. Any likeness to existing proposals is coincidental. When possible examples are given from my own proposals.

RailsConf 2016

I only recently started taking notes while reviewing proposals for RailsConf. There were over 500 to read through, and at some point, many start blending together into a generic proposal blob. I'll mostly be focusing on this CFP experience. The CFP is split into 4 parts - title, abstract, details, and pitch. The App used for the CFP is open source. From the README:

The heart of the proposal is the title and abstract. These two will show up in your program and schedule. They are required fields and have limits on how long they can be. The details field is for reviewers/organizers only and is there to allow the speaker to show 'what's behind the curtain' like an outline or other explanations that don't belong in the abstract. The pitch is there to allow the speaker to sell you on why this talk should be in your event.

Let's start off simple. Try not to make overt typos in anything you submit. They stick out like a sore thumb in otherwise potentially well written submissions. It seems trivial, but when your talk comes up as the 70th submission that a reviewer is looking at that day it might break their brain and hurt your chances. If you're not a native English speaker or you're awful with grammar like me, ask a friend for a review. I'll also contract with editing services: Draft's "Ask a Pro" feature is quick and easy.

Pitch

The first round of reviews is blind, however in the "Pitch" section some people are able to give lots more specific details without identifying themselves than others. I found myself leaning towards reading the "Pitch" section first as it was one area where some talk proposals really stood out. To me this section was all about the submitter's credibility. Why should I listen to them? Are they an amazing speaker and will give a great performance? Are they an expert in a field that they can speak authoritatively on? Do they have some unique experience that makes their content special or different? You can't identify yourself here, but you can identify traits or facts about yourself. Did you win "best comedic presentation" at your local toastmasters? Were you in every theatre play and musical production in school? Did you write an open source tool or library that deals heavily with the topics involved? Have you spoken before? It doesn't have to be at a conference, tell me about your love for speaking at school or user groups, something that indicates your general ability to give a well thought out and prepared talk. Where did you speak? How was it received? What audiences did you resonate with? Did you write a book? Where do you work? Do you hate with a passion due to ? How did you find the topic you're submitting about, and what makes you the best person to speak on it?

Another way to think of a pitch section is if two people submitted otherwise identical proposals, how would you sell yourself as being the best candidate to speak?

A Cliche is Like...

Don't use cliches, everyone use's cliches and it makes your proposal blend in. If you feel the pull of using a phrase everyone has heard "a million times", ask yourself if it adds to what you're trying to convey. For getting out of this habit I recommend Word Hero. Along the line of cliche's avoid absolutes in your writing unless you know they're true

  • "Everyone's heard of": I haven't heard about this before, am I nobody?
  • "Obviously": If it's so obvious, why did you have to write it? Drop the word.
  • "We've all heard": Then it probably isn't worth speaking about.

These types of "absolute" phrases only work when you really know your audience, even then they sound weak. Not to be "beating a dead horse" and absolutely NEVER use "absolute" phrases.

Details

The details section is where you can show how much you've thought about your topic. Did you just wake up one morning and think "hmm, maybe I could talk about Texas BBQ sauce history" or is this something that's been brewing in the back of your brain for the last six months? The details section is where I'm interested in specifics. Facts, figures, and concepts. When I read it, I want to form a mental picture of someone walking around the stage going from topic to topic building towards a central argument, or whatever the point of the talk is.

BTW, your talk should have a point. When someone walks away from your talk they might only take away 2-3 things with them. Those things should be in your proposal, the details section seems like a reasonable place to put them. As much as I like to see specific content in the details section, I don't want 60 bullet points of in depth takeaways. You only have <30-60> minutes depending on the conference and talk slot. 60 bullet points leaves you with 30 seconds per each, give your topic room to breathe. Don't give a comprehensive overview of EVERYTHING in a field, you won't have time. Go deep in one part.

If you know what you want to talk about, but you're not sure how you want to structure it, check out Jeff Casimir's great 'Prototypical Conference Talks' it has some do-s and some don'ts.

Medium over Message

One big deciding factor for me on whether a talk should be accepted or not, is asking "is this the right medium for this content". Before you submit a proposal on a topic, consider writing a blog post about it. If you were able to say everything you wanted to in 1 post, then it's probably not a good candidate for a talk. Written words work well for reference and getting started, materials, and for comprehensive rundowns. Talks on the other hand favor emotional communication. What is the story behind this refactoring? Are you taking a boring topic and making it interesting or memorable somehow in a way that only a live performance could do justice to? Imagine your talk is finished and has been recorded by Confreaks. Under what circumstances would someone say "hey you should watch a video about " and link to your video? If you see a high possibility of that happening, then your topic is well suited for the stage.

The detail section is where you can also get into sharing your personality as it relates to the topic. What are the themes? Are there jokes you plan to tell? How will the things that make you unique co-mingle with your talk topic? Statements like "This is the talk I wish I could have attended a year or two ago" are great if they lead to helping the reviewer uniquely understand your position on a topic. How does your talk make the world a better place for the people who come to see it?

Something that I liked when consuming the details section is a bullet point list that would show the general flow of information and ideas. Something I didn't like is when proposals went so far as to give minute markers telling how long they would spend talking about each thing. Estimates are okay but I don't want it to look like a stenographer's transcript, it's mind numbing.

Did I mention I feel like talks are a good time to share information through stories? If you think the pitch section is about selling yourself and your credibility, then the details section is about selling your topic presentation flow, takeaways, and the stories that bind them all together.

Abstract

Imagine you bump into me in an elevator, you're about to go give your talk. I ask if I should go, you have 400 words to sell me on attending. What would you say? For many conferences the title and abstract are the only things they ask for. I'm seeing more and more organizers seeking more info like RailsConf does. Either way you'll have to write one, and the better it is, the better your chances are of getting accepted.

An abstract to me is a pure marketing pitch. You can google on how to "write good copy" and see a ton of "do this" and "don't do that" lists. It may sound cheesy but many of the techniques work well at grabbing attention and keeping it. Start off with a bang, if your first sentence isn't good they won't read the rest. Here's a few of my opening sentences of talks that I've gotten accepted:

  • What do you do when a maintainer leaves a project with over 44 million downloads?
  • Underneath the beautiful veneer of our Ruby libraries lies a twisted tangle of writhing guts.
  • Heroku has deployed millions of web apps.
  • Good tests are isolated, they’re repeatable, they’re deterministic.
  • Level up your programming game, and change the world.
  • Run your app faster, with less RAM and a quicker boot time today. How? With science!
  • If you've ever misspelled a word while searching on Google, you've benefited from decades of distance algorithm development.

I'm not going to claim they're all master works, but they're at least kinda interesting. Another key point in abstracts is brevity. Use short sentences. Short sentences are concise. Short sentences are rich. Short sentences are powerful. Short. Sentences.

Remove unnecessary words, obviously. Remove soft or hedging statements "sometimes", "maybe", etc. It's okay to be a little hyperbolic in an abstract. Instead of "your tests might be slower than you may like" it's okay to shorten to "your tests are slow". Attendees will self select so that statement will likely be true. If my tests are fast, i don't need your talk. Being concise in an abstract shows me that you know the core essence of what you want to talk about and you know how to extract and distill it.

Once you've grabbed attention, you'll want to make sure to give your reader enough information to determine whether or not they should see the talk. Is it an advanced topic? Very technical? Any prerequisites? I like being specific on these points. Here's some of my "in this talk" statements from proposals that have gotten accepted over the years:

  • In this talk we'll break down some popular distance measurements and see how they can be implemented in Ruby. We'll look at real world applications with some live demos.
  • You will learn how to stay sane in the face of insane testing conditions, and how to use these tests to deconstruct a monolith app.
  • We will cover what it takes to go from no-grammer to a senior level programmer and everything in between. Don’t come to this talk if you don’t want to be motivated, you don’t want to succeed, and certainly if you don’t want a good swift kick in your Ruby programming pants.
  • We'll look at real world use cases where small changes resulted in huge real world performance gains. You'll walk away with concrete and actionable advice to improve the speed of your app, and with the tools to equip your app for a lifetime of speed.
  • In this talk you'll learn how to use simple and sharp Ruby tools to slice into large libraries with surgical precision. Turn your impossible bugs into pull requests, and level up your programming skills by Dissecting Ruby with Ruby.
  • We've taken a look at the most common patterns and boiled down the best of our advice in to 12 simple factors that can help you build your next app to be stable, successful, and scalable. After this talk you'll walk away with in depth knowledge of web framework design patterns and practical examples of how to improve your application code.

Tell me what I can expect to learn, what I can expect to take away. It's not a requirement, but it helps to cut some of that marketing hyperbole with some straight talk.

A well written abstract is almost like a piece of technological poetry. It is more than the sum of it's words. Speaking of words one thing I found helps in my abstract creative process, is to make word clouds. Given a topic like "security" or "performance" I write down as many other words come to mind. I then stack rank them based on which are the most interesting. I write about 10-20 different intro sentences. About 3-4 different copies of the "takeaway" sentences, and about 5-10 outro sentences. I then mix them up until they feel right.

When working on an abstract get feedback, from anyone. How does it make them feel? What do they think the talk is about? What types of things would they consider about the abstract before deciding to come or not? If they respond "good", that's not helpful press them for details. It helps if that someone has submitted to conferences, but it isn't required. If you find yourself working with experienced submitters, don't let them re-write or edit out your voice. Don't force a sentence in that won't fit just because it sounds great on its own. Write lots, throw away lots.

Title

The best wisdom for writing titles is to save it for last. I hate this advice because I always forget about it until I've spent 4 hours up front trying to write a good title. Instead my advice is set a timer for 3 minutes, write as many titles as you can. Pick your favorite, then write the rest of your submission. When you're done go back and throw away the title and re-write it. Chances are your original title won't match your final talk concept. Try to spend a bit more time writing down title ideas, maybe 10-15 minutes. Try testing your favorite 2-4 on a few people and then go with your gut as to the best one.

Try to use descriptive words or action statements in the title. Really avoid cliches here, I'm really not interested in "how [you] stopped worrying and learned to love the <blank>".

Don't alienate your audience through jargon. Your title should say something about your talk. If it's an "in" joke or an acronym don't use it. I get it that you know what HATEOS is, but some of your attendees or conf selection committee might not. (No one used this acronym in this year's CFP to my knowledge I'm not picking on anyone's proposal).

As a rule don't put anything in your title or abstract that your attendee would not understand unless they already attended. You can lean on your knowledge of the conf, it's likely that attendees of RailsConf will have heard of REST, so you can probably use it, but unless you're talking explicitly about that topic maybe it's not super helpful. When in doubt lean on being more descriptive, and less creative. You can also use two titles with a colon if it helps. I did this for "Millions of Apps: What we've Learned". The title is probably the least important thing to me as a reviewer, but likely the most important thing to an attendee in terms of picking your talk. Spending time working on your "pitch" and your "details" actually can help improve the quality of talk you give, spending hours on your title won't. Budget your time accordingly, don't dwell on the perfect name™.

Submission notes

If you want to increase your chance of getting a talk accepted I have two pieces of advice.

1) Submit more than one talk to each conference 2) Submit to 3x the number of conferences you want to speak at

Speaking is a numbers game. The great players in baseball only hit the ball 1/3 of the time at best. I find I only get accepted to every 1 out of 3 conferences I apply to. There's a zillion reasons why your talk wasn't accepted that has nothing to do with you.

  • Too similar to another already accepted
  • Too different to the other talks accepted
  • Technical, and they needed more non-technical content
  • Too advanced
  • Too geared towards beginners
  • All over the place
  • Too specific
  • Not the right fit for attendees
  • Your talk isn't unique (gave at other confs)
  • Your talk is too immature (haven't given at any other confs)

The list goes on. Trying to predict what a conference needs and writing to that is impossible. Most reviewers don't even know until they have read all the proposals. I try to at bare minimum always write one technical and one non-technical leaning talk. I like to have 3 or so proposals in my back pocket that I would be willing or interested in presenting on. Writing 3 proposals takes 3 times as long, but they can be reused for other confs. When I am in a writing mood, it is easier to write 3 talks than to try to find 3 separate times. If you find writing a specific proposal idea is too hard or painful, it's a good sign that isn't a great topic to talk on, imagine having to expand that proposal to a full 30 minutes.

Lots of good talks get rejected to every conference. Rejection never gets any easier. My one piece of advice is to focus on the future of submitting to other confs. The reviewers likely won't have time to give you specific feedback on why a talk wasn't accepted. Even if they do you might not like what you hear, it probably won't be actionable to future talks. I've never been given feedback from conference organizers. Instead I focus on bright spots.

Look at the talks that were accepted, what did they have in common with your proposal? What did they have that was different? Maybe you can ask some of the people who got talks accepted to share their details & pitch (things that are not put on the schedule). They don't have to, of course, but if they do it is more data for you. Don't be snarky about it though, show genuine appreciation and interest. "I saw your abstract on the program and thought it sounded really interesting, I definitely want to go. I'm trying to get better at submitting to conferences would you be willing to share your 'details' and 'pitch' in a public blog post or a private gist?".

Again, it may have been blind luck that their talk was chosen, or maybe they did something implicitly different than you, or maybe it was bad luck that your talk wasn't chosen. The only thing you can do is try to get more data points, just don't try to read too much into each of those. Here's the three proposals I submitted this year (reviews are blind and I'm programmatically prohibited from voting on your my talks, reviewers are encouraged to submit talks). The "Saving Sprockets" was chosen, why? Who knows. Don't take these as good or bad examples, they just are. What did you like about them? What did you dislike? What have I recommended to do here that I didn't do well in my proposals?

I really want to give the "Everyday Heroes" sometime, it's more of a non-code talk that I think has really broad appeal with some useful ways to think about the world. However I seem to be better at writing proposals for more technical content. BTW. don't comment on the gist, GitHub doesn't send any notifications you can send comments via @schneems on twitter.

Your First Conf Proposal

So you've read all of this, you've decided to take the plunge. What should you do first? I think you should go speak at a user group. I help to run Austin on Rails and we practically have to hunt down people to give talks. If you approach a local user group organizer with a talk idea they'll most likely give you a slot, probably sooner than you were expecting.

If things go well, consider submitting the same talk to a conference. If they go poorly reflect on why, look for local mentors that speaks well, ask them to coffee to give you feedback on how to get better. There's lots of books, and videos on improving technical speaking. Watch good talks. Watch technical conference talks, and also watch talks in other fields like TED that are captivating. What makes them good? You don't have to present exactly like them, but did someone use a technique you really liked? Steal it, and incorporate it. Writers, write. Speakers speak. I've talked at user groups that have been standing room only 100+ people. I've spoken at major industry conferences with less than a dozen people in the room. Just because it is "local" doesn't mean it doesn't count as speaking.

In general you won't get much actionable feedback when presenting. I've had someone tell me my talk was "too advanced" and "too beginner" from different people at the same talk. If you have an in depth opinion on someone's talk, right after they gave it is not a good time. ("Hey I liked your talk" is always appreciated even if you have criticisms that you want to share later). Let the adrenaline settle, wait for a day maybe. Ask before giving advice "can I share some feedback?". Ask if there is any specific type of feedback they are looking for. Maybe they are working on the enunciation, or stage presence, maybe they feel the technical content could be tweaked.

Don't blindly give feedback, speaking is a performance. Even the best of intentioned feedback from closely trusted friends can damage egos. Try to focus on the positive, or if there was negative focus on remediation items instead of why things were bad. Speakers, the best time to get feedback is before a conference. Sit a co-worker or loved one down and present to them for an hour, get immediate feedback. Give them a pen and paper to write notes. If you're not practicing for the timing of your talk let them interrupt you with questions. You should consider baking answers of those questions into your talk. You can keep notes on a paper too. Speaking is a skill, if you practice it with appropriate feedback loops you will get better.

As an organizer of Keep Ruby Weird, my number one priority is that my audience will walk away and say "Wow, those speakers were amazing, I'm very glad I came". When we are going through the 2nd or 3rd round we don't do blind review, I have few enough speakers that I can google for videos of them presenting. A few sound bites can go a long way. It's certainly not required, but I take it as an irrefutable sign that you've at least put work into speaking as a craft. If you don't have Confreaks at your local meetup, try turning any presentation into a screencast and putting it online. Our conference doesn't penalize "non-unique" content i.e. you've given it before. We want it to be well delivered and executed, it's okay if other people have seen the talk before, it won't get moldy. It's okay if english is your second language, it's okay if the other speakers in the lineup don't look or act like you, it's okay if you don't have a famous twitter handle. A good story, well presented can be unstoppable.

Don't feel like speaking is some rite of passage every developer must go through to advance. I loved theatre in high school. I was awarded "biggest ham" in my first musical of which I had maybe 2 or 3 lines. I get a rush when I speak. I also love teaching, I was an adjunct professor at UT for a short while. I use the pressure of giving talks as a kind of peer review platform for things I'm trying to figure out. Being forced to present on a topic means I can't fake or pretend to know the subject matter. Speaking for me is as much of a personal journey as a public outreach.

I once thought that speaking was how I got to the "next level". I don't think that's true anymore. I know lots of programmers I really respect that don't speak or speak infrequently. There are other ways to express yourself, podcasts, blog posts, technical papers, writing books, pull request, GitHub issues, etc. Speaking to check off some professional bucket-list item will probably not end well. If you get up on the stage because you have something to say and you have something to get out of it, you'll be great.

Now comes the disclaimer, all these opinions and advice are mine only. I'm very biased towards my own successes and failures, try to get a diversity of opinions. Remember that they are opinions, not facts. YMMV. You can see the organizers and review team on the RailsConf about page. Maybe find them at RailsConf, thank them for reading proposals till their eyes fell out and ask them for their thoughts.

I forgot to mention, make the last sentence in your abstract somewhat memorable, preferably short, even better if it's actionable. Now go forth and write better proposals!


Richard is a junior woodworker who dabbles in programming for Heroku. He has opinions, and dad jokes. Follow @schneems on Twitter for more.

Easier Gem Releases with Bundler Release Tasks

If you maintain a gem and aren't using Bundler's release rake tasks you're missing out. If you have a well maintained gem, then the best practice is to tag a release every time you push a new gem version to RubyGems.org. This helps users to see differences between versions. For example you can compare releases on the Heroku Ruby Buildpack https://github.com/heroku/heroku-buildpack-ruby/compare/v142...v143. Bundler comes with a Rake task that simplifies tagging a release and pushing a version to RubyGems.

To use the rake tasks, you'll need a Rakefile in your project. In that Rakefile you'll need to add:

require 'bundler/gem_tasks'

You can see this line in derailed_benchmarks. Now you can see available tasks by running:

$ bundle exec rake -T
rake build            # Build derailed-0.1.0.gem into the pkg directory
rake clean            # Remove any temporary products
rake clobber          # Remove any generated files
rake install          # Build and install derailed-0.1.0.gem into system gems
rake install:local    # Build and install derailed-0.1.0.gem into system gems without network access
rake release[remote]  # Create tag v0.1.0 and build and push derailed-0.1.0.gem to Rubygems

To cut a new release, you rev the version of your gem, commit to git and then run:

$ bundle exec rake release

That will create a tag, push to GitHub and push your latest version to Rubygems. It's that easy. Using the task also ensures that the latest code you have locally is on GitHub, I've been guilty before of fixing a problem and forgetting to push to master after I cut a RubyGems release. If you're not tagging your gem release versions on GitHub, you should start. If you already are tagging manually, you can save yourself a few commands with this simple trick. Go now, I rake release you.