[A picture of private offices at Fog Creek Software]

Joel on Software

How to Ship Anything

by Joel Spolsky
Tuesday, December 13, 2005

When we started selling the Aardvark DVDs on our website, we didn't think it would be so hard to pack and ship them. First of all, we didn't expect there would be so many, and we conveniently forgot some of the little problems like filling out customs forms which turned out to be big nightmares.

For the first batch that we shipped we did things in a very ad-hoc way. I used Microsoft Word's Mail Merge feature to print many of the labels; for international orders I wrote a little Access application that filled out forms on the USPS web site, and so on.

The actual shipping turned out to be quite difficult. It was amazing how small ergonomic problems turn into huge headaches when you're shipping thousands of orders to 60 different countries. For example, the customs form generated by the USPS web site needed to be signed. We had tons of these. We tried to "sign" them by running them through the laser printer again and printing a couple of signature images in the correct place. This worked OK on one printer, but every other printer in the office jammed up when you gave it paper that had already come out of a laser printer. Why is that? Eventually, of course, the printer which could print signatures ran out of toner. It was a Dell. Dell doesn't let office products stores sell their toner. The only way to get toner was to order it from Dell and pay a lot of money for overnight delivery.

My estimate was that it took about three minutes of labor per order, and we only got it that low because we were batching them up. Worse, it took someone skilled in SQL queries and Mail Merge to create the labels.

Last weekend, I thought, there's got to be an easier way. I spent some time researching tools on the Internet for making this stuff easier, and on Monday, I started building our new Super Duper Shipping System, aka FogShip, which took about three days to set up, program, and debug.

Here's what the physical system looks like.

The whole process is controlled by a single computer running Microsoft Access. The shipping data itself lives in SQL Server.

Every day when you're ready to ship things, you click on a button in Access which causes a stack of packing slips to print out. A typical packing slip is shown at right.

Why Microsoft Access? I was skeptical myself. I've never, ever used the Access "report" feature in my life; I always imagined it was intended for old-fashioned people who need to have their data printed out for some obscure reason and can't fathom the idea of looking things up on a computer.

Well, it turns out that Access reports are perfect for generating packing slips. This is what they were born to do. Since the data is already in SQL Server, it took no more than a couple of hours to layout and design the report exactly the way I wanted it.

Two other things you'll notice about our packing slips, learned from hard experience. First of all, instead of printing them on a standard-sized sheet of paper, I printed them on 5x8 cards. This has two big advantages. First, they fit into the envelopes we use for shipping most books, CD-ROMs, and DVDs without folding. This really makes a difference when you have a lot of shipping to do. Second, because the card stock is a little bit stiffer than paper, it's easier to shove them into the envelope.

You'll also notice the bar code printed in the top corner. There are many different schemes for printing barcodes, but if you're printing your own barcodes, the easiest barcode system to use is something called Code 39. Other barcode systems want you to add a checksum at the end of the barcode and that means you have to write a little bit of code to calculate the checksum. But Code 39 embeds the the error correction protocol in each letter, which means that you can get a Code 39 font that works just like a font without writing any software.

When you're ready to start shipping you grab a packing slip and scan it.

I didn't really know which barcode scanner to buy, and no matter how hard I tried, I couldn't find any online reviews of barcode scanners. I did find out that the kind of scanner I wanted was a USB keyboard wedge scanner. That means that it has a USB port, which makes connection simple, and it behaves exactly like a keyboard as far as your computer is concerned. I also found out that I wanted a laser scanner, not a CCD scanner, because it works at a distance. I ended up buying a Wasp WLS-9000 along with the stand which you can see in the picture. So far it's been great.

Setting up the barcode reader was the easiest thing in the world. Plug it in to a USB port, and you're done. It comes with a whole book of barcodes that you can scan to configure it to behave in many interesting ways, which you can throw away. Without any setup, when you scan a barcode, your scanner will type the letters that barcode represents on the keyboard and press Enter.

In FogShip, scanning the barcode launches a VBA process which does three things.

First, it marks the order as shipped in our online database, so the customer gets an email to let them know their order is on the way. Technically speaking, it would be more accurate to tell them their order shipped when the post office actually came by and picked up their order, but that enhancement will take more programming and will have to wait.

The second thing that happens when you scan the barcode is that it displays the information from the packing slip on a second large screen in a giant font. That way you can immediately shove the packing slip into the envelope... you don't have to keep it around any more just to keep track of what you're packing. This was a lesson learned from the first round of shipping, where we had to keep the packing slip outside the envelope until the last minute so that we would know what to pack and what the shipping method was; keeping the packing slip out until the last minute was just one more annoying thing that made the whole process less fluid.

Third, it prints a mailing label, and, for international orders, a customs slip.

To print USPS mailing labels with postage, you really only have three choices. You can use the USPS website ("Click 'n' Ship"), but that is designed for home users shipping one or two items. It is not designed to be automated and it always prints lots of instructions which you throw away. Since it relies on Adobe Acrobat Reader for the label, the process of printing is cumbersome and doesn't work well unless you use expensive, full page 8.5 x 11 labels from a laser printer. Anyway, Click 'n' Ship is not the way to go.

The other two choices are Stamps.com and Endicia. Both of them have ways to programmatically print a label.

Endicia had a couple of advantages over Stamps.com for our application: it had a decent tool for laying out custom forms and labels exactly the way you wanted, and it had all the documentation on their website. Stamps.com required you to sign up for a developer program, so it took a while to get the documentation we needed, and we needed that thing yesterday, so we just went with Endicia.

Endicia's system for printing labels couldn't be easier. You create an XML file with all the shipping information and launch their app with the name of that XML file on the command line. It spits out a label and exits, creating a new XML file with tracking information and status information. The stamps.com system, as far as I know, is based on ActiveX, which would have worked fine for our application, too.

Now... let's talk about spitting out a label. If you're doing more than three or four labels a day, you'll want a label printer, and if you want the whole process to go quickly, you'll want a really fast label printer, not a laser printer that has to warm up. Everybody recommended Zebra which makes high-end, industrial strength label printers. We went with the Z4Mplus, which spits out a 4x6 label in less than a second. Not only that, it peels the label for you if you get the optional peeler (sign me UP!) This thing is really, really cool. And if you get Direct Thermal labels, you don't need to buy a ribbon or ink or toner or anything... it sort of burns the print onto the label.

Next problem: customs forms for international orders. A customs form looks like this:

The green bit on the left is a sticky label which you peel off and stick to the envelope. The white part is just plain paper, attached via perforation. You have to fill out the whole thing with details like price, an exact description of the products, how much they weigh, and you have to sign both sides. Filling these things out is a pain in the butt.

The first trick was to find a printer that could print on 4" x 7" paper, the size of the customs forms, without messing up the sticky label part. It also had to be able to print pretty close to the edge of the page, it couldn't depend on manually feeding each form, and it had to look good enough so that an image of the signature wouldn't look too fake. It had to be fast at printing and not take a long time warming up, or it would slow down the process.

The printer we found which met all these criteria was the HP LaserJet 2420. We bought two of them (the other one prints the packing cards). It can hold about 100 blank forms in the envelope tray... it turned out that these forms are almost exactly the size of Monarch envelopes which is a standard format for most programs.

The setup software that comes with this printer is completely awful and crashed trying to install on a brand new Windows XP computer. It took several hours of fooling around with the drivers before this thing would print properly. In the meantime, it was printing, but super-slowly, and we couldn't figure out why. I'm pretty shocked that in this day and age HP is still shipping printers that just can't be set up by normal humans.

Back to Microsoft Access, where I created a report for the customs form. Using a ruler I carefully measured the position of each of the fields on the paper form and set up the Access report accordingly. It worked great, even producing a decent facsimile of a signature on the signature line!

The last step in the process is attaching any other flotsam, like Airmail or Priority Mail stickers.

And, tada! You're done.

Shipping an international order now takes about 35 seconds, down from 3 minutes, and can be done by anyone, whether or not they have SQL and Mail Merge skills. Domestic orders are even faster since they don't need customs forms. Most of all, it's all really fun.


Have you been wondering about Distributed Version Control? It has been a huge productivity boon for us, so I wrote Hg Init, a Mercurial tutorial—check it out!

Next:

The Perils of JavaSchools



Want to know more?

You’re reading Joel on Software, stuffed with years and years of completely raving mad articles about software development, managing software teams, designing user interfaces, running successful software companies, and rubber duckies.



About the author.

I’m Joel Spolsky, co-founder of Trello and Fog Creek Software, and CEO of Stack Exchange. More about me.

© 2000-2014 Joel Spolsky