<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: kellan-elliott-mccrea</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/kellan-elliott-mccrea.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2026-02-25T03:30:32+00:00</updated><author><name>Simon Willison</name></author><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2026/Feb/25/kellan-elliott-mccrea/#atom-tag" rel="alternate"/><published>2026-02-25T03:30:32+00:00</published><updated>2026-02-25T03:30:32+00:00</updated><id>https://simonwillison.net/2026/Feb/25/kellan-elliott-mccrea/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://laughingmeme.org/2026/02/09/code-has-always-been-the-easy-part.html"&gt;&lt;p&gt;It’s also reasonable for people who entered technology in the last couple of decades because it was good job, or because they enjoyed coding to look at this moment with a real feeling of loss. That feeling of loss though can be hard to understand emotionally for people my age who entered tech because we were addicted to feeling of agency it gave us. The web was objectively awful as a technology, and genuinely amazing, and nobody got into it because programming in Perl was somehow aesthetically delightful.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://laughingmeme.org/2026/02/09/code-has-always-been-the-easy-part.html"&gt;Kellan Elliott-McCrea&lt;/a&gt;, Code has &lt;em&gt;always&lt;/em&gt; been the easy part&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/perl"&gt;perl&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/agentic-engineering"&gt;agentic-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/deep-blue"&gt;deep-blue&lt;/a&gt;&lt;/p&gt;



</summary><category term="perl"/><category term="generative-ai"/><category term="kellan-elliott-mccrea"/><category term="agentic-engineering"/><category term="ai"/><category term="llms"/><category term="deep-blue"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2025/Mar/2/kellan-elliott-mccrea/#atom-tag" rel="alternate"/><published>2025-03-02T14:16:32+00:00</published><updated>2025-03-02T14:16:32+00:00</updated><id>https://simonwillison.net/2025/Mar/2/kellan-elliott-mccrea/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://fiasco.social/@kellan/114092761910766291"&gt;&lt;p&gt;Regarding &lt;a href="https://simonwillison.net/2025/Mar/2/hallucinations-in-code/"&gt;the recent blog post&lt;/a&gt;, I think a simpler explanation is that hallucinating a non-existent library is a such an inhuman error it throws people. A human making such an error would be almost unforgivably careless.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://fiasco.social/@kellan/114092761910766291"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;&lt;/p&gt;



</summary><category term="ai-assisted-programming"/><category term="generative-ai"/><category term="kellan-elliott-mccrea"/><category term="ai"/><category term="llms"/></entry><entry><title>A Link Blog in the Year 2024</title><link href="https://simonwillison.net/2024/Jun/9/a-link-blog-in-the-year-2024/#atom-tag" rel="alternate"/><published>2024-06-09T00:10:45+00:00</published><updated>2024-06-09T00:10:45+00:00</updated><id>https://simonwillison.net/2024/Jun/9/a-link-blog-in-the-year-2024/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://laughingmeme.org//2024/06/08/a-link-blog-in-2024.html"&gt;A Link Blog in the Year 2024&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Kellan Elliott-McCrea has started &lt;a href="https://laughingmeme.org/links/"&gt;a new link blog&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Like many people I’ve been dealing with the collapses of the various systems I relied on for information over the previous decades. After 17 of using Twitter daily and 24 years of using Google daily neither really works anymore. And particular with the collapse of the social spaces many of us grew up with, I feel called back to earlier forms of the Internet, like blogs, and in particular, starting a link blog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I've been leaning way more into link blogging over the last few months, especially now my own link blog &lt;a href="https://simonwillison.net/2024/Apr/25/blogmarks-that-use-markdown/"&gt;supports markdown&lt;/a&gt;. This means I'm posting longer entries, somewhat inspired by &lt;a href="https://daringfireball.net/"&gt;Daring Fireball&lt;/a&gt; (my own favourite link blog to read).&lt;/p&gt;
&lt;p&gt;Link blogging is a pleasantly low-pressure way of writing online. Found something interesting? Post a link to it, with a sentence or two about why it's worth checking out.&lt;/p&gt;
&lt;p&gt;I'd love to see more people embrace this form of personal publishing.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://fiasco.social/@kellan/112583726435885054"&gt;@kellan&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/blogging"&gt;blogging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;&lt;/p&gt;



</summary><category term="blogging"/><category term="kellan-elliott-mccrea"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2024/Jun/9/kellan-elliott-mccrea/#atom-tag" rel="alternate"/><published>2024-06-09T00:08:12+00:00</published><updated>2024-06-09T00:08:12+00:00</updated><id>https://simonwillison.net/2024/Jun/9/kellan-elliott-mccrea/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://laughingmeme.org//2024/05/12/what-we-mean-to-others.html"&gt;&lt;p&gt;Much like Gen X is sometimes the forgotten generation (or at least we feel that way), the generation of us who grew up with an internet that seemed an unalloyed good fall awkwardly into the middle between those who didn’t grow up with it, and those for whom there has always been the whiff of brimstone, greed, and ruin around the place.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://laughingmeme.org//2024/05/12/what-we-mean-to-others.html"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2023/Feb/27/kellan-elliott-mccrea/#atom-tag" rel="alternate"/><published>2023-02-27T20:12:10+00:00</published><updated>2023-02-27T20:12:10+00:00</updated><id>https://simonwillison.net/2023/Feb/27/kellan-elliott-mccrea/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://fiasco.social/@kellan/109938461268750936"&gt;&lt;p&gt;Just a reminder, the way you evaluate yourself as a leader is how much both the individuals and teams in your organization grow in their capacity to achieve hard goals. Everything else is a distraction.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://fiasco.social/@kellan/109938461268750936"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/management"&gt;management&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/leadership"&gt;leadership&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="management"/><category term="leadership"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2023/Jan/24/kellan-elliott-mccrea/#atom-tag" rel="alternate"/><published>2023-01-24T05:26:47+00:00</published><updated>2023-01-24T05:26:47+00:00</updated><id>https://simonwillison.net/2023/Jan/24/kellan-elliott-mccrea/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://laughingmeme.org/2023/01/23/software-and-its-discontents-part-2-complexity.html"&gt;&lt;p&gt;Large teams spend more time dealing with coordination and are more likely to reach for architecture and abstractions that they hope will reduce coordination costs, aka if I architect this well enough I don’t have to speak to my colleagues. Microservices, event buses, and schema free databases are all examples of attempts to architect our way around coordination. A decade in we’ve learned that these patterns raise the cost of reasoning about a system, during onboarding, during design, and during incidents and outages.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://laughingmeme.org/2023/01/23/software-and-its-discontents-part-2-complexity.html"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/software-architecture"&gt;software-architecture&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/microservices"&gt;microservices&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="software-architecture"/><category term="microservices"/></entry><entry><title>Building Layoffs on a Healthy Foundation</title><link href="https://simonwillison.net/2022/Sep/1/layoffs/#atom-tag" rel="alternate"/><published>2022-09-01T18:11:57+00:00</published><updated>2022-09-01T18:11:57+00:00</updated><id>https://simonwillison.net/2022/Sep/1/layoffs/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://kellanem.com/notes/layoff-foundations"&gt;Building Layoffs on a Healthy Foundation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Kellan provides some valuable guidance for running layoffs in as humane a way as possible.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://twitter.com/kellan/status/1565381024980279309"&gt;@kellan&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/management"&gt;management&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="management"/></entry><entry><title>Dropbox: Sharing our Engineering Career Framework with the world</title><link href="https://simonwillison.net/2021/Jul/13/dropbox-engineering-career-framework/#atom-tag" rel="alternate"/><published>2021-07-13T23:31:48+00:00</published><updated>2021-07-13T23:31:48+00:00</updated><id>https://simonwillison.net/2021/Jul/13/dropbox-engineering-career-framework/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://dropbox.tech/infrastructure/sharing-our-engineering-career-framework-with-the-world"&gt;Dropbox: Sharing our Engineering Career Framework with the world&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Dropbox have published their engineering career framework, with detailed descriptions of the different levels of the engineering (as opposed to management) career track and what is expected for each one. I’m fascinated by how different companies handle the challenge of keeping career progression working for engineers without pushing them into people management, and this as a particularly detailed and well thought-out implementation of that.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://twitter.com/kellan/status/1414630899598209031"&gt;@kellan&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/careers"&gt;careers&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/dropbox"&gt;dropbox&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="careers"/><category term="dropbox"/></entry><entry><title>Friday wins and a case study in ritual design</title><link href="https://simonwillison.net/2019/Jun/8/friday-wins-and-case-study-ritual-design/#atom-tag" rel="alternate"/><published>2019-06-08T18:14:57+00:00</published><updated>2019-06-08T18:14:57+00:00</updated><id>https://simonwillison.net/2019/Jun/8/friday-wins-and-case-study-ritual-design/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://kellanem.com/notes/friday-wins"&gt;Friday wins and a case study in ritual design&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“Culture is what you celebrate. Rituals are the tools you use to shape culture.”


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/management"&gt;management&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="management"/></entry><entry><title>Questions for a new technology</title><link href="https://simonwillison.net/2019/Feb/6/questions-new-technology/#atom-tag" rel="alternate"/><published>2019-02-06T04:10:08+00:00</published><updated>2019-02-06T04:10:08+00:00</updated><id>https://simonwillison.net/2019/Feb/6/questions-new-technology/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://kellanem.com/notes/new-tech"&gt;Questions for a new technology&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Kellan poses 8 questions which should be asked of any technology that is being proposed for inclusion in an existing tech stack. I’m particularly fond of “Will this solution kill and eat the solution that it replaces?”. My rule of thumb these days is that new technology either needs to make something possible that isn’t possible at all with the existing stack, or it needs to represent at least a 3X productivity improvement in order to compensate for the switching and retraining costs across a large team.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2018/Mar/10/kellan-elliott-mccrea/#atom-tag" rel="alternate"/><published>2018-03-10T01:11:19+00:00</published><updated>2018-03-10T01:11:19+00:00</updated><id>https://simonwillison.net/2018/Mar/10/kellan-elliott-mccrea/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://medium.com/@kellan/onward-510d88ae4a9e"&gt;&lt;p&gt;I’m still a novice to the healthcare space, but if I walked away with a single insight, it’s that the problems of the US healthcare system are very tractable. The high cost and mixed results are unique to our system. There are incumbents fighting fiercely to maintain the status quo, but no more so than in other industries that technology has overturned. The regulatory environment is complex, but again not uniquely so. There are industries where one has to dig to find the problems that technology is well suited to solve, but US healthcare, an industry that communicates via fax, is not one of them.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://medium.com/@kellan/onward-510d88ae4a9e"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/healthcare"&gt;healthcare&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="healthcare"/></entry><entry><title>Tip: Flickr standard photo response as slideshow</title><link href="https://simonwillison.net/2011/Jan/25/tip/#atom-tag" rel="alternate"/><published>2011-01-25T03:51:00+00:00</published><updated>2011-01-25T03:51:00+00:00</updated><id>https://simonwillison.net/2011/Jan/25/tip/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://laughingmeme.org/2011/01/24/tip-flickr-standard-photo-response-as-slideshow/"&gt;Tip: Flickr standard photo response as slideshow&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Neat trick—you can construct a URL to Flickr’s slideshow widget that includes the results of any API method, including the all-powerful &lt;code&gt;flickr.photos.search&lt;/code&gt;. It’s a shame you can’t embed the resulting slideshow in an iframe.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/apis"&gt;apis&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flickr"&gt;flickr&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/widgets"&gt;widgets&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;&lt;/p&gt;



</summary><category term="apis"/><category term="flickr"/><category term="kellan-elliott-mccrea"/><category term="widgets"/><category term="recovered"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2010/May/18/sharecropping/#atom-tag" rel="alternate"/><published>2010-05-18T18:21:00+00:00</published><updated>2010-05-18T18:21:00+00:00</updated><id>https://simonwillison.net/2010/May/18/sharecropping/#atom-tag</id><summary type="html">
    &lt;blockquote cite="http://laughingmeme.org/2010/05/18/minimal-competence-data-access-data-ownership-and-sharecropping/"&gt;&lt;p&gt;With Flickr you can get out, via the API, every single piece of information you put into the system. [...] Asking people to accept anything else is sharecropping. It’s a bad deal. Flickr helped pioneer “Web 2.0″, and personal data ownership is a key piece of that vision. Just because the wider public hasn’t caught on yet to all the nuances around data access, data privacy, data ownership, and data fidelity, doesn’t mean you shouldn’t be embarrassed to be failing to deliver a quality product.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="http://laughingmeme.org/2010/05/18/minimal-competence-data-access-data-ownership-and-sharecropping/"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/data"&gt;data&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flickr"&gt;flickr&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sharecropping"&gt;sharecropping&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/web20"&gt;web20&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;&lt;/p&gt;



</summary><category term="data"/><category term="flickr"/><category term="kellan-elliott-mccrea"/><category term="sharecropping"/><category term="web20"/><category term="recovered"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2010/Jan/25/kellan/#atom-tag" rel="alternate"/><published>2010-01-25T08:11:02+00:00</published><updated>2010-01-25T08:11:02+00:00</updated><id>https://simonwillison.net/2010/Jan/25/kellan/#atom-tag</id><summary type="html">
    &lt;blockquote cite="http://laughingmeme.org/2010/01/24/4294967295-and-mysql-int20-syntax-blows/"&gt;&lt;p&gt;If you’re ever debugging a problem and you see the number 42-mumble-mumble-mumble-7295 you’ve run out of 32-bit storage. If you see 2-mumble-mumble-mumble-647 (2147483647) you’ve run out of signed 32-bit storage. 167-mumble-mumble-15 (16777215) you’ve run out of 24-bits and 65-mumble-mumble-35 (65535) you’ve run out of 16-bits of integers.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="http://laughingmeme.org/2010/01/24/4294967295-and-mysql-int20-syntax-blows/"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mysql"&gt;mysql&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/integers"&gt;integers&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="mysql"/><category term="integers"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2009/Apr/12/flickr/#atom-tag" rel="alternate"/><published>2009-04-12T16:00:41+00:00</published><updated>2009-04-12T16:00:41+00:00</updated><id>https://simonwillison.net/2009/Apr/12/flickr/#atom-tag</id><summary type="html">
    &lt;blockquote cite="http://revcanonical.wordpress.com/2009/04/12/revcanonical-bookmarklet-and-designing-shorter-urls/"&gt;&lt;p&gt;We’re using the same trick on flic.kr to avoid having to maintain a look up database, though we’re using base 58.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="http://revcanonical.wordpress.com/2009/04/12/revcanonical-bookmarklet-and-designing-shorter-urls/"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/flickr"&gt;flickr&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/revcanonical"&gt;revcanonical&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/urls"&gt;urls&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/base58"&gt;base58&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;&lt;/p&gt;



</summary><category term="flickr"/><category term="revcanonical"/><category term="urls"/><category term="base58"/><category term="kellan-elliott-mccrea"/></entry><entry><title>rev=canonical bookmarklet and designing shorter URLs</title><link href="https://simonwillison.net/2009/Apr/11/revcanonical/#atom-tag" rel="alternate"/><published>2009-04-11T17:37:55+00:00</published><updated>2009-04-11T17:37:55+00:00</updated><id>https://simonwillison.net/2009/Apr/11/revcanonical/#atom-tag</id><summary type="html">
    &lt;p&gt;I've watched the proliferation of URL shortening services over the past year with a certain amount of dismay. I care about the health of the web and try to ensure that URLs I am responsible will last for as long as possible, and I think it's very unlikely that all of these new services will still be around in twenty years time. Last month &lt;a href="http://simonwillison.net/2009/Mar/8/twitter/"&gt;I suggested&lt;/a&gt; that the Internet Archive start mirroring redirect databases, and last week I was &lt;a href="http://simonwillison.net/2009/Apr/3/tinyurl/"&gt;pleased to hear&lt;/a&gt; that Archiveteam, a different organisation, had &lt;a href="http://archiveteam.org/index.php?title=TinyURL"&gt;already started crawling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The most recent discussion was kicked off by &lt;a href="http://joshua.schachter.org/2009/04/on-url-shorteners.html"&gt;Joshua Schachter&lt;/a&gt; and &lt;a href="http://www.scripting.com/stories/2009/03/07/solvingTheTinyurlCentraliz.html"&gt;Dave Winer&lt;/a&gt;, and &lt;a href="http://laughingmeme.org/2009/04/03/url-shortening-hinting/" title="URL Shortening Hinting"&gt;a solution has emerged&lt;/a&gt; driven by some lightning fast hacking by Kellan Elliott-McCrea. The idea is simple: sites get to chose their preferred source of shortened URLs (including self-hosted solutions) and specify it from individual pages using &lt;code&gt;&amp;lt;link rev="canonical" href="... shorter URL here ..."&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By hosting their own shorteners, the reliability should match that of the host site - and the amount of damage caused by a major shortener going missing can be dramatically reduced.&lt;/p&gt;

&lt;p&gt;I've been experimenting with this new pattern today. Here are a few small contributions to the wider discussion.&lt;/p&gt;

&lt;h4&gt;A URL shortening bookmarklet&lt;/h4&gt;

&lt;p&gt;Kellan's &lt;a href="http://revcanonical.appspot.com/"&gt;rev=canonical service&lt;/a&gt; exposes rev=canonical links using a server-side script running on App Engine. An obvious next step is to distil that logic in to a bookmarklet. I decided to combine the rev=canonical logic with my &lt;a href="http://simonwillison.net/2008/Aug/27/jsontinyurl/"&gt;json-tinyurl&lt;/a&gt; web service (also on App Engine), which allows browsers to lookup or create TinyURLs using a cross-domain JSONP request. The resulting bookmarklet will display the site's rev=canonical link if it exists, or create and display a TinyURL link otherwise:&lt;/p&gt;

&lt;p&gt;Bookmarklet: &lt;a href="javascript:(function(){var url=document.location;var links=document.getElementsByTagName('link');var found=0;for(var i = 0, l; l = links[i]; i++){if(l.getAttribute('rev')=='canonical'||(/alternateshort/).exec(l.getAttribute('rel'))) {found=l.getAttribute('href');break;}}if (!found) {for (var i = 0; l = document.links[i]; i++) {if (l.getAttribute('rev') == 'canonical') {found = l.getAttribute('href');break;}}}if (found) {prompt('URL:', found);} else {window.onTinyUrlGot = function(r) {if (r.ok) {prompt('URL:', r.tinyurl);} else {alert('Could not shorten with tinyurl');}};var s = document.createElement('script');s.type='text/javascript';s.src='http://json-tinyurl.appspot.com/?callback=onTinyUrlGot&amp;amp;url=' +document.location;document.getElementsByTagName('head')[0].appendChild(s);}})();"&gt;Shorten&lt;/a&gt; (drag to your browser toolbar)&lt;/p&gt;

&lt;p&gt;You can also grab the &lt;a href="http://gist.github.com/93591"&gt;uncompressed source code&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Designing short URLs&lt;/h4&gt;

&lt;p&gt;I've also implemented rev=canonical on this site. I ended up buying a new domain for this, since simonwillison.net is both difficult to spell and 17 characters long. I ended up going with swtiny.eu - 9 characters, and keeping tiny in the domain helps people guess the nature of the site from just the URLs it generates. Be warned: the DNS doesn't appear to have finished resolving yet.&lt;/p&gt;

&lt;p&gt;For the path component, I turned to a variant of base 62 encoding. Decimal integers are represented using 10 digits (0-9), but base 62 uses those digits plus the letters of the alphabet in both lower and upper case. A 13 character integer such as 7250397214971 compresses down to just 8 characters (CDeIPpOD) using base62. My &lt;a href="http://www.djangosnippets.org/snippets/1431/"&gt;baseconv.py module&lt;/a&gt; implements base62, among others. I considered using base 57 by excluding o, O, 0, 1 and l as being too easily confused but decided against it.&lt;/p&gt;

&lt;p&gt;This site has three key types of content: entries, blogmarks and quotations. Each one is a separate Django model, and hence each has its own underlying database table and individual ID sequence. Since the IDs overlap, I need a way of separating out the shortened URLs for each content type.&lt;/p&gt;

&lt;p&gt;I decided to spend a byte on namespacing my shortened URLs. A prefix of E means an entry, Q means a quotation and B means a blogmark. For example:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;samp&gt;http://swtiny.eu/EZ8&lt;/samp&gt;: Entry with ID 1584&lt;/li&gt;
    &lt;li&gt;&lt;samp&gt;http://swtiny.eu/BBEQ&lt;/samp&gt;: Blogmark with ID 4108&lt;/li&gt;
    &lt;li&gt;&lt;samp&gt;http://swtiny.eu/QE5&lt;/samp&gt;: Quotation with ID 279&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using upper case letters for the prefixes, I can later define custom paths starting with a lower case letter. I also have another 23 upper case prefix letters reserved in case I need them.&lt;/p&gt;

&lt;p&gt;I &lt;a href="http://twitter.com/simonw/status/1496864191"&gt;asked on Twitter&lt;/a&gt; and consensus opinion was that a 301 permanent redirect was the right thing to do (as opposed to a 302), both for SEO reasons and because the content will never exist at the shorter URL.&lt;/p&gt;

&lt;h4&gt;Implementation using Django and nginx&lt;/h4&gt;

&lt;p&gt;I run all of my Django sites using Apache and &lt;a href="http://code.google.com/p/modwsgi/"&gt;mod_wsgi&lt;/a&gt;, proxied behind &lt;a href="http://nginx.net/"&gt;nginx&lt;/a&gt;. Each site gets an Apache running on a high port, and nginx deals with virtual host configuration (proxying each domain to a different Apache backend) and static file serving. I didn't want to set up a full Django site just to run swtiny.eu, especially since my existing blog engine was required in order to resolve the shortened URLs.&lt;/p&gt;

&lt;p&gt;Instead, I implemented the shortened URL direction as just another view within my existing site: &lt;samp&gt;http://simonwillison.net/shorter/EZ8&lt;/samp&gt;. I then configured nginx to invisibly requests to &lt;samp&gt;swtiny.eu&lt;/samp&gt; through to that URL. The correct incantation took a while to figure out, so here's the relevant section of my nginx.conf:&lt;/p&gt;

&lt;pre&gt;&lt;code class="nginx-conf"&gt;server {
    listen 80;
    server_name www.swtiny.eu swtiny.eu;
    location / {
        rewrite (.*) /shorter$1 break;
        proxy_pass http://simonwillison.net;
        proxy_redirect off;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;proxy_redirect off&lt;/code&gt; is needed to prevent nginx from replacing &lt;samp&gt;simonwillison.net&lt;/samp&gt; in the resulting location header with &lt;samp&gt;swtiny.eu&lt;/samp&gt;. My Django view code is relatively shonky, but if you're interested you can &lt;a href="http://www.djangosnippets.org/snippets/1430/"&gt;find it here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The nice thing about this approach is that it makes it trivial to add custom URL shortening domains to other projects - a quick view function and a few lines of nginx configuration are all that is needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The bookmarklet now supports the rev attribute on A elements as well - &lt;a href="http://simonwillison.net/2009/Apr/11/revcanonical/#c44088"&gt;thanks for the suggestion&lt;/a&gt;, Jeremy.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/bookmarklets"&gt;bookmarklets&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/dave-winer"&gt;dave-winer&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/joshua-schachter"&gt;joshua-schachter&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/revcanonical"&gt;revcanonical&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tinyurl"&gt;tinyurl&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/urls"&gt;urls&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="bookmarklets"/><category term="dave-winer"/><category term="django"/><category term="joshua-schachter"/><category term="kellan-elliott-mccrea"/><category term="projects"/><category term="python"/><category term="revcanonical"/><category term="tinyurl"/><category term="urls"/></entry><entry><title>Streams, affordances, Facebook, and rounding errors</title><link href="https://simonwillison.net/2009/Mar/19/streams/#atom-tag" rel="alternate"/><published>2009-03-19T14:02:31+00:00</published><updated>2009-03-19T14:02:31+00:00</updated><id>https://simonwillison.net/2009/Mar/19/streams/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://laughingmeme.org/2009/03/18/streams-affordances-facebook-and-rounding-errors/"&gt;Streams, affordances, Facebook, and rounding errors&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
I asked Kellan about scaling activity streams the other day. Here he suggests the best technique is not to promise a perfect stream (like Twitter does)—Facebook used to get away with 80% loss of update messages, but their new redesign has changed the contract with their users.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/activitystreams"&gt;activitystreams&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/facebook"&gt;facebook&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/scaling"&gt;scaling&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/twitter"&gt;twitter&lt;/a&gt;&lt;/p&gt;



</summary><category term="activitystreams"/><category term="facebook"/><category term="kellan-elliott-mccrea"/><category term="scaling"/><category term="twitter"/></entry><entry><title>Quoting Kellan Elliott-McCrea</title><link href="https://simonwillison.net/2008/Sep/29/secretsauce/#atom-tag" rel="alternate"/><published>2008-09-29T15:29:34+00:00</published><updated>2008-09-29T15:29:34+00:00</updated><id>https://simonwillison.net/2008/Sep/29/secretsauce/#atom-tag</id><summary type="html">
    &lt;blockquote cite="http://laughingmeme.org/2008/09/29/on-the-freebase-custom-tuple-store-graphd/"&gt;&lt;p&gt;The only down side is everyone I’ve talked to at Freebase seems pretty solid on this being their proprietary secret sauce, because a good, fast scalable open source tuple store might actually jump start a real semantic (small-S) web after all these years.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="http://laughingmeme.org/2008/09/29/on-the-freebase-custom-tuple-store-graphd/"&gt;Kellan Elliott-McCrea&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/freebase"&gt;freebase&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/open-source"&gt;open-source&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/proprietary"&gt;proprietary&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphd"&gt;graphd&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/semanticweb"&gt;semanticweb&lt;/a&gt;&lt;/p&gt;



</summary><category term="kellan-elliott-mccrea"/><category term="freebase"/><category term="open-source"/><category term="proprietary"/><category term="graphd"/><category term="semanticweb"/></entry><entry><title>Twitter, or Architecture Will Not Save You</title><link href="https://simonwillison.net/2008/May/29/twitter/#atom-tag" rel="alternate"/><published>2008-05-29T01:16:04+00:00</published><updated>2008-05-29T01:16:04+00:00</updated><id>https://simonwillison.net/2008/May/29/twitter/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://laughingmeme.org/2008/05/28/twitter-or-architecture-will-not-save-you/"&gt;Twitter, or Architecture Will Not Save You&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Kellan is not an armchair architect. He also doesn’t mention Rails once. Well worth reading.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/architecture"&gt;architecture&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rails"&gt;rails&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/twitter"&gt;twitter&lt;/a&gt;&lt;/p&gt;



</summary><category term="architecture"/><category term="kellan-elliott-mccrea"/><category term="rails"/><category term="twitter"/></entry><entry><title>Flickr Place IDs</title><link href="https://simonwillison.net/2008/Jan/19/flickr/#atom-tag" rel="alternate"/><published>2008-01-19T07:34:38+00:00</published><updated>2008-01-19T07:34:38+00:00</updated><id>https://simonwillison.net/2008/Jan/19/flickr/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://laughingmeme.org/2008/01/18/flickr-place-ids/"&gt;Flickr Place IDs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;code&gt;flickr.places.find&lt;/code&gt;, &lt;code&gt;flickr.places.resolvePlaceURL&lt;/code&gt; and &lt;code&gt;flickr.places.resolvePlaceID&lt;/code&gt; combine to provide a really useful, lightweight not-quite-a-geocoder API. It's a shame you can't search for places by providing a latitude/longitude point yet.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/api"&gt;api&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flickr"&gt;flickr&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flickrplaces"&gt;flickrplaces&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geocoding"&gt;geocoding&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/geospatial"&gt;geospatial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;&lt;/p&gt;



</summary><category term="api"/><category term="flickr"/><category term="flickrplaces"/><category term="geocoding"/><category term="geospatial"/><category term="kellan-elliott-mccrea"/></entry><entry><title>Crowdvine, iCalico, Pathable, a Study in Collusion</title><link href="https://simonwillison.net/2007/Jul/12/foo/#atom-tag" rel="alternate"/><published>2007-07-12T23:09:27+00:00</published><updated>2007-07-12T23:09:27+00:00</updated><id>https://simonwillison.net/2007/Jul/12/foo/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://laughingmeme.org/2007/07/11/foo-crowdvine-icalico-pathable-a-study-in-collusion/"&gt;Crowdvine, iCalico, Pathable, a Study in Collusion&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Stitching sites together around a single user database using subdomains and simple signed cookies.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/collusion"&gt;collusion&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/crowdvine"&gt;crowdvine&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/foocamp"&gt;foocamp&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/icalico"&gt;icalico&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pathable"&gt;pathable&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/signedcookies"&gt;signedcookies&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sso"&gt;sso&lt;/a&gt;&lt;/p&gt;



</summary><category term="collusion"/><category term="crowdvine"/><category term="foocamp"/><category term="icalico"/><category term="kellan-elliott-mccrea"/><category term="pathable"/><category term="signedcookies"/><category term="sso"/></entry><entry><title>PHP Library Tips</title><link href="https://simonwillison.net/2003/Aug/13/libraryTips/#atom-tag" rel="alternate"/><published>2003-08-13T18:11:58+00:00</published><updated>2003-08-13T18:11:58+00:00</updated><id>https://simonwillison.net/2003/Aug/13/libraryTips/#atom-tag</id><summary type="html">
    &lt;p&gt;Kellan Elliott-McCrea (author of the popular &lt;a href="http://magpierss.sourceforge.net/"&gt;Magpie RSS parser&lt;/a&gt;): &lt;a href="https://laughingmeme.org/2003/08/05/a-few-tips-for-writing-useful-libraries-in-php/"&gt;A Few Tips for Writing Useful Libraries in PHP&lt;/a&gt;. Kellan makes the interesting observation that &lt;acronym title="PHP: Hypertext Preprocessor"&gt;PHP&lt;/acronym&gt; encourages a culture in which most development occurs in the context of either full applications or C extensions, with few people devoting themselves to releasing libraries.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/kellan-elliott-mccrea"&gt;kellan-elliott-mccrea&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/php"&gt;php&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rss"&gt;rss&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="kellan-elliott-mccrea"/><category term="php"/><category term="rss"/></entry></feed>