<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Notes on Technology Leadership</title>
  <subtitle>Musings on technology, leadership, and building teams.</subtitle>
  <link href="https://blog.david-jensen.com/feed.xml" rel="self"/>
  <link href="https://blog.david-jensen.com/"/>
  <updated>2026-03-15T00:00:00.000Z</updated>
  <id>https://blog.david-jensen.com/</id>
  <author>
    <name>David Jensen</name>
  </author>
  
  <entry>
    <title>How to Frame a Technology Strategy</title>
    <link href="https://blog.david-jensen.com/how-to-frame-a-technology-strategy/"/>
    <updated>2026-03-15T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/how-to-frame-a-technology-strategy/</id>
    <content type="html"><![CDATA[
      <p>In my <a href="/learnings-from-building-a-technology-strategy-in-a-silo/">previous post</a>, I shared the lessons from building my first technology strategy — around connecting to company strategy, building a shared understanding of the current state, managing complexity, and getting input from the wider organisation.</p>
<p>The strategy had a number of merits — it brought two recently merged engineering cultures closer together and gave us a shared focus during a complex migration period. But it wasn't the decision-making tool I'd hoped for, and I knew we could do better.</p>
<p>When it came time to start our strategy refresh, those lessons shaped every decision about how we approached it.</p>
<h2>What we did differently</h2>
<p>This time we had a clear company strategy to anchor to. Storio2030 (our company vision) gave us the end state that was missing the first time around. That meant the technology strategy could focus on the &quot;how&quot; rather than defining the &quot;why&quot; or the &quot;what&quot; — those were already established.</p>
<p>We also made a deliberate choice not to build a functional strategy. Technology at Storio is an enabler for almost everything the business does. A strategy created by technology for technology would repeat the same mistake. This needed to be an organisational enablement strategy with input, challenge and feedback woven in from across the business.</p>
<p>Finally we were clear up front about what success looked like. Not a document that sat on a shelf but a strategy that enabled better and faster decisions by the teams closest to the work. That meant the output needed to be accessible, actionable and something people could engage with without a thirty-page read.</p>
<h2>The vision I shared internally</h2>
<p>To kick off the process I wrote a foreword for the organisation framing why this strategy matters and how I wanted us to approach it. Here it is as I shared it.</p>
<hr>
<p>I first started writing code to solve business problems in the year 2000, during the dot com boom. I was frustrated with having to manually aggregate electricity meter data from thousands of sources to accurately trade energy. It quickly became clear to me that leveraging technology for efficient solutions would soon become the standard approach for every business.</p>
<p>Fast forward 25 years and that prediction has been proved right. Sure, the technology has moved on quite a lot — from Excel VBA macros to LLM-generated code — but finding efficient and scalable solutions to enable happier customers and successful business outcomes is still the fundamental reason why we exist as a Technology function. Technology is an enabler to almost every facet of Storio. This strategy aims to ensure success through aligned context, a clear vision for where we are going, and repeatable ways of both finding and solving the biggest blockers and opportunities on our path to Storio2030.</p>
<p>This strategy will primarily be focused on the &quot;How&quot; Storio approaches building technology. The &quot;Why&quot; is derived from our company vision, and the &quot;What&quot; is defined by our core business outcomes: the Storio2030 vision and other strategic themes such as our Digital Experience Strategy (a cross-functional strategy defining our customer-facing product direction). Crucially, this is not a siloed Technology functional strategy; it's an organisational enablement strategy. My ambition is for it to influence and empower everyone who uses technology across Storio — Product, Operations, Commercial, Marketing, Finance and HR. There will be functional elements, but this strategy's creation process cannot happen in a vacuum. We need to actively weave input, challenge, and feedback from the entire organisation.</p>
<p>Storio was created during the Web 2.0 era, enabled by the seismic shift from film to digital. At the same time web capability improvements removed friction — no longer did you need to download an application — significantly widening our customer base. AI is poised to enable the next, equally significant capability shift. This strategy will ensure that once again Storio can capitalise on a technology shift to significantly accelerate our ambitions.</p>
<p>Ultimately, this strategy's success won't be measured by its documentation, but by the quality of the decisions it enables to make Storio2030 a reality. Those decisions must be made quickly and efficiently by the teams closest to the work. To achieve this, the strategy needs to be created in a way that enables wide input and challenge to create a clear vision and actionable tenets. This will be both top-down and bottom-up, combining our ambitious aspirations with the practical reality of where Storio is today.</p>
<hr>
<h2>Why this framing mattered</h2>
<p>Sharing this foreword was deliberate. It set the tone for how the strategy would be created — not handed down from technology but built collaboratively. It gave people permission to challenge and contribute from day one.</p>
<p>The impact showed up quickly. Working group conversations shifted from &quot;what does technology want to do?&quot; to &quot;what do we need to enable?&quot; and the engagement at our offsite showed people felt genuine ownership of the direction. That was the signal we were on the right track.</p>
<p>In future posts I'll share the structure that emerged from this process — the framework we used to turn this vision into actionable tenets and how we kept the organisation involved throughout.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Learnings from My First Technology Strategy</title>
    <link href="https://blog.david-jensen.com/learnings-from-building-a-technology-strategy-in-a-silo/"/>
    <updated>2026-03-08T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/learnings-from-building-a-technology-strategy-in-a-silo/</id>
    <content type="html"><![CDATA[
      <p>The first strategy I created as CTO of Storio brought two recently merged engineering cultures closer together — and that was genuinely valuable. But looking back, I learned a lot about how to make a strategy land with more impact.</p>
<p>Before we kicked off a strategy refresh I first spent time reflecting on why. I want to share those lessons here because I think they apply well beyond my own experience and because they have fundamentally shaped how I approach strategy now.</p>
<h2>The context</h2>
<p>Around six months into the role I kicked off my first strategy process. Storio had recently been through a merger and every function was tasked with creating a vision for their future state. I also had two completely separate engineering organisations, each accountable for their own systems. Bringing them together under a shared direction felt like the right first move.</p>
<p>It was — and the process taught me a lot about what I'd do differently next time.</p>
<h2>No company strategy to anchor to</h2>
<p>At the time the company's long term strategy was still being developed. That meant I was building a technology strategy in isolation, without a clear end state to work towards.</p>
<p>Strategy should be reductive. It should make decisions easier by giving people a lens to evaluate options against. Without a guiding company view that lens doesn't exist and technology becomes a function optimising for its own goals rather than enabling the business.</p>
<p><strong>The lesson:</strong> don't build a functional strategy ahead of the company strategy it needs to serve. If the business direction isn't clear yet, focus on foundations and how to enable future decision making.</p>
<h2>Not enough time understanding the current state</h2>
<p>We moved too quickly into defining the future without making sure everyone was on the same page about today. And by everyone I don't just mean the technology function. I mean the executive team and the other functions that depend on technology every day.</p>
<p>This gap didn't show itself immediately. It surfaced when we started implementing and realised that the wider organisation wasn't aligned with the need for change or the reasoning behind it.</p>
<p><strong>The lesson:</strong> invest in current state alignment before you define the future. Make sure the people who will need to support and fund the change understand and agree on the problems you are solving.</p>
<h2>Shorter strategies are easier to use</h2>
<p>Without clear outcomes defined up front we ended up producing a twenty-page strategy document. The debates that went into it were genuinely valuable but the artefact itself was too detailed for anyone outside the process to engage with. It required too much time investment to read, let alone act on.</p>
<p>The specificity also worked against us. We had come from a highly autonomous culture with a diverse technology stack. Being prescriptive about solutions meant every recommendation carried a huge cost of change across different teams and contexts.</p>
<p><strong>The lesson:</strong> define how the strategy will be used in practice before you start creating it. If the goal is organisational alignment then the format needs to be accessible, concise and flexible enough to accommodate different starting points.</p>
<h2>Too insular to drive real change</h2>
<p>This was a technology strategy built by the technology function. The problem is that technology at Storio is an enabler for almost everything the business does. Delivering on our strategy required changes across multiple functions, not just our own.</p>
<p>Because it was created in isolation it lacked the cross-functional buy-in needed to drive those wider changes. The size, format and complexity of the document compounded this by making it hard to socialise beyond our own teams.</p>
<p><strong>The lesson:</strong> if your function is an enabler then your strategy cannot live inside your function alone. The people who need to change their behaviour to make it real need to be part of creating it.</p>
<h2>What this taught me</h2>
<p>Looking back, these challenges share a common thread. Each one was a symptom of building in a silo. Siloed from company strategy, from shared understanding of the current state, from how the output would be used, and from the people who needed to act on it.</p>
<p>The strategy wasn't without value — it played a real role in bringing two recently merged engineering cultures together, especially as we navigated complex migrations. But I knew we could go further, particularly in making it a tool that drove decisions and enabled change across the whole organisation.</p>
<p>These learnings have fundamentally shaped how I think about creating strategy and what I believe makes one successful. In my <a href="/how-to-frame-a-technology-strategy/">next post</a> I share how these lessons shaped the framing for our strategy refresh — and the internal vision that kicked it off.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Listen First: What a Merger Taught Me About Leading Technology</title>
    <link href="https://blog.david-jensen.com/listen-first-what-a-merger-taught-me-about-leading-technology/"/>
    <updated>2026-02-28T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/listen-first-what-a-merger-taught-me-about-leading-technology/</id>
    <content type="html"><![CDATA[
      <p>I first stepped into the CTO role at Storio role less than six months after we had completed a merger. I had previously been VP Engineering for one of the merged companies and had acted up into the role for periods before that. It is something I had wanted for a long time but it felt very different when I was finally in the hot seat.</p>
<p>Overnight my engineering scope doubled and expanded to include Data, IT and Security for the first time. I became accountable for two different  organisations, Albelli the company we merged with was based in Amsterdam which brought cultural differences I hadn't anticipated. For the first six months all I wanted to do was not make any mistakes. Especially with our first peak season coming where we made a significant amount of our profit.</p>
<h2>Finding My Voice on the Executive Team</h2>
<p>Stepping into the Executive team broadened my focus and I was forced to engage in a number of topics that previously I hadn't. This was one of my first challenges. As a technology leader how much should I engage with commercial, operational and strategic topics that I had limited context on?</p>
<p>There is no right answer to this but my personal value is to only speak when I am adding value. It is easy to feel like you need to have an opinion on everything when you join a senior leadership team. I chose not to and still take this approach to this day. It took time to build the context needed to contribute meaningfully outside of technology and I think that patience paid off.</p>
<h2>The Importance of Face to Face</h2>
<p>With a distributed workforce one of my first tasks was to get around to all of our locations and meet everyone. This can be quite daunting for someone on the introverted side of the personality spectrum but it was hugely important.</p>
<p>Human connections forged face to face are so beneficial when you are going through change. Not because of the small talk but because you need to find the people who will give you honest feedback. The ones who will tell you what is actually going on rather than what they think you want to hear. Those relationships became invaluable and I could not have built them over video calls alone.</p>
<h2>The Culture Lesson That Changed Everything</h2>
<p>One of my bigger challenges was navigating culture. Country culture, company culture and functional culture all intertwined with each other and I underestimated the complexity of this.</p>
<p>My biggest insight came from a Principal Engineer about six months in. I had really felt like I was being ignored in a number of areas and could not figure out why. Digging into it I learned that my default approach of giving my opinion first and then asking for others to challenge and adapt based on logic was not working. Culturally it felt like I was telling everyone what to do. So it was ignored.</p>
<p>Simply by inverting that approach to asking for others opinions first and then sharing mine the impact I was able to have changed dramatically. It sounds so obvious written down but when it is your default communication style it is a hard thing to recognise without someone being honest enough to tell you.</p>
<h2>Setting the Direction</h2>
<p>Things really started to click when we began writing our first Technology Strategy. Rather than debating approaches in meetings, we wrote down our processes, principles and cultural expectations for how we work with technology. Having it on paper meant both teams could engage with the ideas without it feeling like one side was imposing on the other. It depersonalised the conversation and began the long process of standardisation.</p>
<p>That foundation helped us navigate our first peak season as a merged entity successfully. We made minimal changes and focused on validating load and features before the traffic spikes. It was not glamorous but it worked.</p>
<p>The process of creating that strategy was genuinely valuable for bringing people together. The strategy itself? That's a <a href="/learnings-from-building-a-technology-strategy-in-a-silo/">different story</a>.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Migrating My Blog with Agentic AI: What I Learned</title>
    <link href="https://blog.david-jensen.com/migrating-my-blog-with-agentic-ai/"/>
    <updated>2026-02-21T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/migrating-my-blog-with-agentic-ai/</id>
    <content type="html"><![CDATA[
      <p>Its been seven years since my last post here, this blog had been sitting on a hand rolled WordPress instance since 2012. Fifty-five posts, hundreds of images, a decade of accumulated plugins and hosting complexity for something that was fundamentally just text and pictures. I'd been meaning to move it to a static site generator and add HTTPS for years. The thing that finally made it happen was using Agentic AI (Claude). My blog has always been a place where I can learn and experiment with both writing and technology, I had forgotten how much I like building things.</p>
<p>This isn't a tutorial. There are plenty of WordPress-to-static migration guides out there. This is more of a reflection on what it's actually like to use an AI coding agent for a real, messy, end-to-end project — and what I learned about how to work with it effectively.</p>
<h2>The Starting Point</h2>
<p>The blog was running on WordPress, hosted on AWS EC2. The content spanned 2012 to 2019 — technical posts about scaling teams, WordPress infrastructure, product development, and engineering leadership. Many posts had embedded images, some had SoundCloud embeds, a couple had image galleries. The URLs had been shared and linked to over the years, so preserving them was non-negotiable.</p>
<p>We chose Eleventy as the target because it's lightweight, flexible, and I didn't need a framework — just a static site generator that could take markdown files and produce HTML.</p>
<h2>What Actually Happened</h2>
<p>The whole migration took about a week of evening sessions. There were several distinct pieces of work, each with their own challenges. The best part of this was it was like working with an agency doing all of the work in the background. I was able to use my extensive experience to break down the process into chunks and then outsource the doing to Claude. Humans doing the thinking with AI doing the doing is going to become more prevalent in the coming weeks, months and year. Even better the support I got wasn't just for coding but for design, tagging and performance.</p>
<p><strong>Extracting the content.</strong> I had a MySQL dump of the WordPress database, so the first job was parsing that to extract the published posts. Claude built a SQL parser in Node.js that could handle WordPress's escaped content, then a migration script that converted the HTML to markdown using Turndown. This gave us the raw material — fifty-five posts converted to markdown, each with structured metadata at the top of the file that tells the site generator how to render it — the title, date, URL, and so on.</p>
<p><strong>Handling the WordPress quirks.</strong> This was the bulk of the work. WordPress has years of accumulated implicit behaviour, and migrating content faithfully means dealing with all of it. SoundCloud shortcodes needed converting to iframe embeds. Caption shortcodes wrapping images needed unwrapping. Heading levels were inconsistent across posts and needed normalising. The <code>wpautop</code> function that WordPress uses to add paragraph tags created formatting issues when converted to markdown — walls of text where there should have been paragraphs. Image galleries were particularly fiddly, stored in a WordPress-specific shortcode format that needed converting to a CSS-only lightbox grid.</p>
<p><strong>Migrating images.</strong> Hundreds of images were still hosted on the old WordPress CDN. Claude built a download script that pulled each image, saved it locally with the right directory structure, and updated the markdown references to point to the local paths. This ran post-by-post so we could verify nothing was missed.</p>
<p><strong>Preserving URLs.</strong> The original WordPress URLs had been shared and linked to over the years. Every single one needed to work on the new site. This meant matching Eleventy's permalink structure to the old WordPress slugs and validating that all fifty-five URLs resolved correctly.</p>
<p><strong>Building the validation suite.</strong> A comprehensive script that checked URL preservation, image integrity, internal links, HTML meta tags, RSS feed entries, and sitemap coverage. This became the safety net for the whole project — every change could be verified automatically against it.</p>
<p><strong>Deployment and infrastructure.</strong> A GitHub Actions pipeline that builds the site, runs validation, syncs to S3, and invalidates the CloudFront cache. Plus the SEO fundamentals: Open Graph tags, canonical URLs, sitemap, robots.txt, and a 404 page.</p>
<p>By the end: 55 posts migrated, 138 images preserved, all original URLs maintained, automated deployment, and a validation suite that gave me confidence nothing was broken.</p>
<h2>What I Learned About Working with AI Agents</h2>
<h3>Batch and iterate, don't try to do everything at once</h3>
<p>The most effective pattern was migrating posts in small batches — typically five at a time — visually checking the output, then fixing whatever was wrong before doing the next batch. Each batch surfaced new edge cases, and fixing them improved the migration script for all subsequent batches.</p>
<p>When I tried to do too many posts at once, the problems compounded and it was harder to see what had gone wrong. Small batches with fast feedback loops worked much better.</p>
<h3>Invest in validation early</h3>
<p>The validation script was one of the best decisions of the project. Once it existed, every subsequent change could be verified automatically. It checked things I would never have manually tested — every single URL preserved, every image reference resolving, every post appearing in the RSS feed.</p>
<p>Building that kind of safety net early freed me up to move faster on everything else. It's the same principle as writing tests before refactoring, applied to a migration.</p>
<h3>The AI is excellent at the tedious parts</h3>
<p>Parsing WordPress SQL dumps. Converting shortcodes. Downloading and re-referencing hundreds of images. Generating consistent content structures. These are the kinds of tasks that would have taken hours of manual effort and been incredibly error-prone. Claude handled them reliably and fast.</p>
<h3>But you need to stay in the loop on decisions</h3>
<p>The places where things went wrong were almost always about context that I hadn't communicated. WordPress has a lot of implicit behaviour — the way <code>wpautop</code> adds paragraph tags, the way galleries are stored, the way internal links are structured. Claude doesn't know your specific WordPress setup unless you tell it, and even then, some things only become apparent when you look at the rendered output.</p>
<p>The most productive pattern was: let Claude do the implementation, but review the output yourself. Not the code — the actual rendered blog posts in the browser.</p>
<h3>The long tail is where the time goes</h3>
<p>The initial migration — getting posts from WordPress into markdown — was maybe 20% of the total effort. The other 80% was everything else: fixing formatting edge cases, handling embeds, getting images right, setting up deployment, SEO, validation. This is true of most software projects, but it's worth remembering when you're estimating how long an AI-assisted project will take.</p>
<h2>Would I Do It Again This Way?</h2>
<p>Without question. What would have been a tedious multi-weekend project became a fun background task across a week. The migration scripts, the validation suite, the deployment pipeline — none of these are things I'd have built if I were doing it manually. I'd have done it by hand, made mistakes, and not had the safety net to catch them.</p>
<p>The experience also changed how I think about using AI for engineering work more broadly. The key insight isn't that AI can write code — it's that AI changes what's worth automating. Tasks that would previously have been too small to justify writing a script for suddenly become worth scripting, because the cost of creating that automation has dropped so dramatically.</p>
<p>That's the real shift. Not &quot;AI writes code for me&quot; but &quot;the economics of automation have fundamentally changed.&quot; And I think we're still in the very early days of understanding what that means.</p>
<p>Claude also wrote this post for me (promise that this won't be the case in the future) based on the existing content and our conversations together.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Scaling Up from Seven to Seventy</title>
    <link href="https://blog.david-jensen.com/scaling-seven-seventy/"/>
    <updated>2019-03-08T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/scaling-seven-seventy/</id>
    <content type="html"><![CDATA[
      <p>In June 2016 I was working for a venture capital backed media startup called The Tab. As the CTO one of my core focus areas was enabling a team of 7 engineers to reinvent student journalism across the UK and US. Having come to the end of a venture funding round I had a decision to make. To stay and help with the next phase of growth, or go elsewhere to focus on my own.</p>
<p>It was one the most difficult professional decisions that I have made, due to the depth which I had sunk into the problem space and the amazing people that I was working with. However my desire was to learn how to run multiple high performing teams concurrently at scale and I had confidence that the team at The Tab was strong enough to do it without me.</p>
<p>I started Photobox on 1st August 2016, since then I have been iterating on people, process and principles. With a goal to enable over 70 people embedded in more than 10 teams to have maximum impact within a private equity investment cycle. By no means has this journey been straight forward or is it finished, however I feel like it is a good time reflect on my thoughts so far.</p>
<h2>Start with principles</h2>
<p>Starting with a set of principles which explain the how and why is a good way to begin a process of alignment around change.</p>
<h2>High trust environments enable more effective change</h2>
<p>Conversations around change are best done in a safe space with high trust. My experience is that this most often exists already within existing team structures. You get much better feedback and can tailor responses to the teams context which keeps the conversation relevant and engaged.</p>
<h2>Start small and iterate</h2>
<p>Start small and iterate applies to teams, org structures and operating models as much as it does to releasing software. Big bang changes tend to need the most support and have potential to cause the most negative impact. We have now moved to a model where we change one team at a time and iterate with learning into the next one. This has allowed us to refine the change process as we go and make sure to embed feedback and build out good content for wider sharing.</p>
<h2>Capacity for change is not uniform</h2>
<p>Change impacts different people and cultures in different ways. When change is constant people can become stuck in the trough of uncertainty and this has a massive impact on their ability to have impact. Understanding that change impacts me in a different way to others helped me take a much more empathetic approach.</p>
<h2>Write things down</h2>
<p>Writing how you want to work down and then debating it with wider and wider circles is a great way to iron out the kinks in an operating model. Google docs collaboration features helped us work through and collate feedback along the way.</p>
<h2>Compromise is necessary for aspirational principles</h2>
<p>With significant size, scale and legacy it will be hard to always respect all of your principles all of the time. What to compromise where and how is key to making sure that trust stays high throughout the change process.</p>
<h2>Matrix management reduces alignment</h2>
<p>Matrix management structures are really hard to scale effectively. Especially when managers have different goals to the individuals that they are accountable for and those don't match team goals.</p>
<h2>Alignment increases impact</h2>
<p>To have the most impact build teams of aligned individuals with a shared goal they helped create and believe they can achieve. Then help them to reduce dependencies and remove impediments.</p>
<h2>Build collaborative processes</h2>
<p>The best external structures to the teams are informal ones that are representative, meet regularly to collaborate on issues and maintain standards. However you need a leader to drive this in order for it to continue over a longer term. If you can create collaborative process where people learn together, regularly talk about issues and are then given time to address them change can be a groundswell rather than trying to push water uphill.</p>
<h2>Aligned autonomy takes time</h2>
<p>Scaling teams to become high performing through aligned autonomy takes time. You need to let teams test their boundaries to enable them to get comfortable with where their constraints lie within their autonomy. This process is best facilitated through regular structured communication with stakeholders.</p>
<h2>Consistency can have a high cost</h2>
<p>The larger the number of teams the greater the overhead to enable consistency. One of the biggest challenges with my engineering background was to understand this. People scale in very different ways than code. The right balance between standardisation and customisation is key. This is changes over time and should be inspected and adapted as you move go.</p>
<h2>Structured external communication is key</h2>
<p>Teams should be able to define and improve their own processes as long as they communicate in a consistent way with stakeholders. The way I think about this is much like a contract for an API define the interactions with the outside world first and as long as they are respected it doesn't matter if the internal workings are different per team.</p>
<h2>Metrics are hard</h2>
<p>Finding the right metric for a team to focus on also takes time and iteration. Teams need to be given the appropriate time to go deep into the problem space to figure this out. This often requires engineering effort and a good reliable data platform.</p>
<h2>Balancing metrics are key</h2>
<p>Commercial goals need to be balanced with quality, performance and security measures that the whole team believe in. This takes time and a level of maturity to get right.</p>
<h2>Accountability</h2>
<p>If multiple people are accountable then no one is accountable.</p>
<h2>Hire smart people</h2>
<p>Make sure that you hire smarter leaders than yourself, co-create a vision, collaborate on a goal, give regular feedback to enable them to have the maximum impact.</p>
<h2>Centre of excellence</h2>
<p>A centre of excellence is a great way to ensure that areas of quality but limited resources are utilised and share knowledge effectively. We have moved to a model where they draw up a contract with teams based on a menu of their services. This ensures that expectations are clear and met. This has really helped as we have moved away from having dedicated resources in teams such as agile coaching and testing.</p>
<h2>Full Stack</h2>
<p>Full stack is a mindset that really can enable teams to have more impact but is good to both train as well as hire. Generalists can also have negative impact on quality so it is a hard balance to get right.</p>
<h2>Effective communication underpins everything</h2>
<p>Communicate, communicate, communicate. Communication scales exponentially I do not.</p>
<h2>Autonomy, Master &amp; Purpose</h2>
<p>Autonomy, mastery and purpose are key to setting teams and individuals up for success. However getting the balance right with autonomy takes time, teams and individuals take longer to find their purpose and you need to think about the balance of experience levels in teams with regards to mastery.</p>
<p>The key learning from the last two and a half years is how hard significant change can be at an organisation level. Timing is key which means approaches need to evolve over time as there is no right answer to a lot of questions. Persistence, belief and drive are key to reach the tipping point where change itself becomes a natural part of the process.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Lessons from 15 months at The Tab a venture capital backed media startup</title>
    <link href="https://blog.david-jensen.com/the-tab-lessons-vc-backed-media-startup/"/>
    <updated>2016-08-01T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/the-tab-lessons-vc-backed-media-startup/</id>
    <content type="html"><![CDATA[
      <p>The last twelve months have been a very turbulent time in the media industry with profit forecasts and jobs being slashed across both digital and print. Growing a sustainable business in the modern diversified world of media is a hard nut to crack. This is even harder when you have to raise funds every 12 months in order to survive. Now that my tenure at <a href="http://thetab.com">The Tab</a> has come to a close I have reflected on what being involved in this for last fifteen months has taught me.</p>
<h2>Consistent revenue growth is more important than fast audience growth</h2>
<p>This is the statement which has changed the most in the last fifteen months. When The Tab raised in 2015 it was to drive audience growth via an American expansion. The revenue following that growth was a secondary concern. Having since been involved in a funding round I can say that this attitude has changed. Clear, consistent and diversified revenues are a huge part of owning your destiny or being able to raise additional funds to grow.</p>
<h2>The free growth years are over</h2>
<p>As most people have noted the free growth years for media are over. Some say Facebook is capping the amount of traffic that it is sending to publishers. They are definitely focused on optimising the type of content displayed to each of their users. Also the more you are locked into their ecosystem the less attractive you are for investment.</p>
<h2>However there are still opportunities for growth</h2>
<p>As Facebook rolls out new initiatives there are still windows of opportunities for growth. Ripped video content for example has been very effectively growing page likes. However you usually need to skate close to the line to make this happen and quickly backfill with proper content once your knuckles get rapped.</p>
<h2>Facebook Instant Articles provide a decent revenue stream</h2>
<p>Considering all the alternatives early indications are that Facebook Instant Articles are a decent revenue stream. With programmatic on mobile still 12-18 months away from where it is on desktop and users demanding a fast experience (as well as Facebook using speed as a Newsfeed ranking factor) this is good news. With auto-fill rates above 95% and decent CPM's so far for The Tab's audience this does seem like a good play until other mobile units catch up.</p>
<h2>Throwing resources at growth does not build a sustainable business</h2>
<p>What is the key driver of your business and revenue? Find that and focus on it relentlessly. It is much easier to build new things rather than fix core issues. Especially when flush with venture capital. Doing more does nothing but move you further away from what you actually need to fix.</p>
<h2>Focus is hard when you are unsure of what you are being measured on</h2>
<p>What matters most? Uniques, revenue, page views, stories published or cost per story? There are so many things you can be measured on at times it can be bewildering. Bottom line is that you need a clear repeatable, scalable and cost effective growth model including a plan for profitability. Everything else should drop out of that.</p>
<h2>There is still a large appetite for great original content</h2>
<p>So much of the media industry has been focused on the most efficient way to repackage content which means that everyone is fighting over the same eyeballs. However there are still a lot of amazing original stories out there you just have to have an efficient way to find them and deliver to a relevant audience.</p>
<h2>Raising money is a full time job</h2>
<p>The time and effort that goes into raising funds is a full time job. It can take many months, hundreds of meetings and due diligence to close out a round. It is a non-linear process as well with many people you meet along the way introducing you to more people to talk to.</p>
<h2>VCs with aligned portfolios</h2>
<p>When selecting a venture capitalist one that has a decent sized aligned portfolio can provide you access to learning and introductions that others can't. In such a competitive industry these insights can be gold dust and definitely worth considering as you search for investment.</p>
<h2>Negative aspects of raising</h2>
<p>Not knowing if you are going to have enough money to continue as your runway is short and terms sheets are close but not signed can really dampen momentum. It takes very strong belief to be able to continue to drive forward in the face of such uncertainty. The volume of feedback you get from pitches can be overwhelming at times. It can be easy for this to become a distraction which can really hurt focus and belief.</p>
<h2>Positive aspects of raising</h2>
<p>Putting your company on the line and distilling everything you down to a slide deck and presenting it hundreds of times can help sharpen your focus. Some of the feedback you receive throughout this process will be valuable, the trick is to figure out which bits. The pressure which comes from this process either makes you or breaks you, at times it can do both in a single day.</p>
<h2>More money, more problems</h2>
<p>One of the biggest losses with fast growth by VC money can be the loss of creativity that comes from constraint. Getting the balance right between hitting short term targets and long term issues is hard.</p>
<p>I am very proud of what we achieved with The Tab and I have every confidence in the team going on to achieve great things. These lessons should give me a great foundation for my next challenge.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Competitively actionable analytics at The Tab</title>
    <link href="https://blog.david-jensen.com/competitively-actionable-analytics-the-tab/"/>
    <updated>2016-05-19T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/competitively-actionable-analytics-the-tab/</id>
    <content type="html"><![CDATA[
      <p>Competitively actionable analytics was a core element of the technology and product strategy at The Tab. The below details how this approach has translated into product and how that went on to affect user behaviour. The Tab had built a set of micro services to data mine Facebook, WordPress and Google Analytics which created a rich dataset in their data warehouse. This was of little value until it was in front of contributors to drive their learning and retention from competitively actionable analytics data.</p>
<h2>The Tab Team</h2>
<p>The Tab's Team analytics platform was created with a main goal of providing actionable analytics data in a competitive framework for individuals and teams. The product aimed to get authors excited about how individual efforts had contributed to their teams overall success. What you see in red is an authors impact on the team performance. Authors are given a clear overview of how each of their recent stories has performed. At the highest level an overview of the top performers is presented as a leaderboard broken down by country and then team, author and story allowing multiple layers of competition and learning across our network.</p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/Leaderboards.png" alt="Team, Reporter and Story Leaderboards"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/team.jpg" alt="Personal Dashboard"></p>
<p>Previous to this project data access was restricted to a small set of users with a Google Analytics login and a high level understanding of custom filters. WordPress also had some stats but only at a team level and they were reasonably hidden within the dashboard.</p>
<h2>Take the data to the people</h2>
<p>The initial launch was a web based front end, the next step was an upgrade of the notification system to be able to send detailed data summaries via email. Distributing data via email increased users to Team by 200% with close to 100% of our active authors logging in monthly. These emails have been able to maintain a 65% open rate and over 10% click through rate after being sent thousands of times.</p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/Weekly.png" alt="Weekly Stats Email"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/Monthly.png" alt="Monthly Stats Email"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/Google-Analytics.png" alt="Usage growth after email"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/team-retention.png" alt="Team Retention"></p>
<h2>Data everywhere</h2>
<p>Analytics are a natural form of gamification and authors were constantly posting screenshots in Facebook groups or Snapchats. To further enable view ability and use stats were embedded on every page of the site for logged in users. The goal was to show as much data as possible within the visual interface that was being used daily. A completely open approach to numbers allowed authors to learn from each others success, there are no restrictions in who can see what data once someone is logged in.</p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/homepage-stats.png" alt="Homepage Stats (Logged In)"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/story-statistics.png" alt="Story Stats (Logged In)"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/profile-stats.png" alt="Author Stats (Public)"></p>
<h2>Real time notifications</h2>
<p>Team has been running successfully since November 2015 delivering a clear path to re-engagement and a core part of The Tab's retention strategy. Since then notifications have been extended to be able to deliver realtime readers stats as well as historical page views. These notifications are delivered by an iOS app The Tab + as well as Facebook Messenger. Push notifications enabled The Tab + to have a very similar level of use and retention to Team. The number of interactions with users has increased as the data is broken down into multiple smaller messages and sent as soon as thresholds are reached. This helped authors to stay excited about their existing story for longer and the more they enjoy process the more likely they are to repeat it.</p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/The-Tab-Plus-iTunes.png" alt="The Tab +"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/Push-notification-coming-to-FB-messenger.jpg" alt="Messenger Push Notification"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/tabitha-interface.jpg" alt="Tabitha Messenger Interface"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/Tab-Plus-GA.png" alt="The Tab + Consistent Engagement"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/the-tab-plus-retention.png" alt="The Tab + Retention"></p>
<h2>Actionable analytics for editorial decision making</h2>
<p>In a bid to take the data to where editors gather a Slack bot was built to enable access to detailed Google and Facebook data just by pasting in a url. Slack channels were created where real time publish and stats updates allowed editors to make decisions about what to promote across our network. Previously editors had to log into multiple systems to gather this information and spend a lot of time filtering. Decisions are now able to be made and discussed in near realtime.</p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/tabitha-stats.png" alt="Tabitha Slack Story Stats"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/tabitha-crosspost.png" alt="Tabitha Slack Channel to Promote Post"></p>
<h2>Big Screen Dashboards</h2>
<p>With authors being served with data in a competitively actionable analytics framework editors within the office were the next to be targetted. Utilising Geckoboard, custom API's and Google Sheets The Tab designed big screen dashboards to drive competition and growth centrally.</p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/uk-dashboard.png" alt="UK Editorial Dashboard"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/us-dashboard.png" alt="US Editorial Dashboard"></p>
<p><img src="/assets/images/competitively-actionable-analytics-at-the-tab/sharing-dashboard.png" alt="Global Sharing Dashboard"></p>
<p>It was a lot of effort to get the data in the right place and then expose it in creative ways to drive learning and performance but now competitively actionable analytics has permeated into The Tab's culture there is no going back.</p>
<h2>The geeky bit</h2>
<p>Millions of rows of data a day are processed using Node.js, Amazon Simple Queue Service, Elastic Beanstalk Workers and MySQL running on RDS. The data is cleaned and then transformed into day, month and year increments as well as aggregated for users and teams. This preprocessing allows very fast recall of any data set. Amazon API gateway using a Node.js Lambda based server less API layer is used for data retrieval. This handles a lot of the standard API paradigms like security and caching which kept the focus on data and user experience. The front end was built in React.js utilising Chart.js for graphing.</p>
<h2>The team</h2>
<p>Big up to Richard Coombes for helping with the backend magic, Matteo Gildone for helping with the frontend magic, Serge Bondarevsky for design and Charlie Gardner-Hill for the dashboards. My focus was on the product management, data collection, data transformation and building the API layer.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Metro10: Going native growing on Android</title>
    <link href="https://blog.david-jensen.com/going-native-growing-metro10-android/"/>
    <updated>2015-08-04T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/going-native-growing-metro10-android/</id>
    <content type="html"><![CDATA[
      <p>I spent nine months in 2014 designing, building and iterating an Android app called Metro10 for the UK Newspaper Metro. This taught me a lot about the benefits and frustrations of native app development and marketing.</p>
<p>The benefits of app users are huge in terms of their engagement and propensity to return daily. Being able to target users via push notifications is a great way to create a trigger habitual consumption of your content. These work best when targeted, relevant and contextual or are quickly turned off.</p>
<p>However these advantages can come at a high cost in terms of acquiring new users. We ran extensive internal banner advertising campaigns on metro.co.uk with limited success. Banners are not the greatest advertising medium, especially mobile banners with a call to action. I think we were naive to think that people would want to install an app whist browsing the web.</p>
<p>You can get much better results from retargeting campaigns based on device and previous visit to your site. Especially if retargeting via Facebook app installs ads. However effective they are at acquiring customers without a clear ROI they were a cost we could not bear.</p>
<p>Metro already had multiple apps for newspaper based consumption. Being yet another app in a constellation hurts when you are the new kid on the block. Visibility from search in the Google Play store also really hurt us due Metro being a very common name. The beta nature of our approach also ruled out using our contacts for App Store promotion.</p>
<p>While developing I released as often as I could. Pushing a daily alpha build and using it on different devices than what I was using for development. This could be quickly rolled out to production every other day once bugs were fixed. The fact it only took hours to get these in the hands of users due to automation was a great advantage of Android.</p>
<p>I ended up with one mobile, one seven inch for coding and one mobile, one seven inch for testing releases. I also managed to get a good group of beta testers in our Google+ Community for feedback.</p>
<p>Google analytics is amazing for tracking performance and especially bugs. Crashes only get sent through to the Play store if people submit but show up in Google Analytics regardless. Due to the limits of our testing (I was the developer and tester) this feedback was invaluable. The sheer number of devices on offer also made a release and fix a necessary approach.</p>
<p>I put a lot of effort into tracking all of the actions that people took within the app. This was a really useful dataset in helping make some big product decisions. I would recommend this approach to all development. It wasn't a large amount of effort to setup either.</p>
<p>Push notifications are very important not just to be clicked on but as a visual reminder of your app on the phone. We utilised Parse from Facebook to get this capability setup without much engineering effort. However these had to be manually sent due to engineering constraints.</p>
<p>The best growth hack we did was run a competition asking for feedback via a Google Doc. For some reason everyone who left us feedback also left us a positive review with really helped us avoid the cold start syndrome with reviews.</p>
<p><img src="/assets/images/metro10-going-native-growing-on-android/metro10-bottom.png" alt="Metro10 app screenshots"></p>
<p>We had a small vocal minority which reached out to us from App Store reviews. Quickly fixing their issues and responding helped us turn a few reviews around and got some great product feedback. My biggest amazement is the amount of people that never upgraded to a new version even though the one they were on was buggy.</p>
<p>With all of our efforts we only managed to get a few hundred daily users. They were and probably still are a very loyal bunch but not enough to maintain ongoing development. Plus I left for a new challenge so that didnt help momentum.</p>
<p>My gut however is that the real issue with apps based around single brand content consumption is that people's habits have changed. Users want to dip in and out of news from their social feeds and friends updates. Without large marketing budgets due to the lack of significant revenue uplift getting on users home pages is a struggle and building enough difference/providing enough content is a struggle to keep them engaged.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How Docker Containers simplify Microservice management and deployment</title>
    <link href="https://blog.david-jensen.com/docker-containers-simplify-microservice-management-deployment/"/>
    <updated>2015-06-12T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/docker-containers-simplify-microservice-management-deployment/</id>
    <content type="html"><![CDATA[
      <p>My recent personal and professional development efforts have taken a microservices approach. This escalated to having 8 services running 3 different languages across 5 different frameworks. After banging my head against the command line for a few days trying to get these to coexist I decided to try Docker containers to attempt streamline and simplify this process.</p>
<p>A software container is a lightweight virtualisation technology that abstracts away the complexity of the operating system and simply exposes ports to the host it runs on. You can run containers on most operating systems and platforms including all major PAAS providers. Keeping the complexity within the container means that host systems can focus on scaling and management. You also get a high level of consistency allowing you to ship containers across different servers or platforms with ease. Essentially building once, saving the image and then pulling on to each of your environments for testing and then deployment.</p>
<p>Utilising the micro service instance per container pattern is a great way to manage a set of services which have the following benefits. Including increased scalability by changing the number of container instances. A great level of encapsulation which means that all services can be stopped started and deployed in the same way. You are able to limit the CPU and memory at a service level. Finally containers are much faster to work with than fully fledged virtual machines and simpler to ship around to platforms for deployment. Amazon for example has built in support via their Container Service as well as Elastic Beanstalk. I have used Ansible for deployment as it has really nice Docker wrapper which makes starting, stoping, pushing and pulling images between servers only a couple of lines of code.</p>
<p>One of the things that you need to watch out for is container reuse as they can get quite large. Base images are a way to minimise this and promote reuse and allow you to be able to control the underlying approach to multiple repositories without code duplication. Each step within the build of the Docker container is cached so only stages that are changed need to be pushed when changed. So be careful around the order that you run scripts leaving the stages that change till last. DockerHub is like a GitHub repository for built images and makes the pushing and pulling images require minimal infrastructure and learning. You can pay for private repositories in the same way that GitHub allows you to, or you can setup your own one if you are that way inclined.</p>
<p>Running Docker containers locally on a Mac is pretty straight forward with Boot2Docker which spins up a local Vagrant box which has the docker daemon running on it and allows you to easily test, build, push and query the main docker repo. Kitematic was also recently acquired by Docker as an alternative to people who are adverse to the command line. There are also a large set of officially maintained base container images for running Node, Jenkins and WordPress amongst many others. You need to understand some patterns around how best to ensure that data is persisted as if you stop a Docker container you loose the data within it. However data only containers are a way around this and a pattern that allows you to persist containers without losing the data or binding it too closely to the underlying operating system.</p>
<p>Microservices allow us to choose the right tool for the job and Docker containers abstract some of the complexity of this approach. Utilising base images promotes code reuse and the Dockerfiles themselves are checked in with the projects so any one who pulls the project can see how it is built which is a huge bonus. Most downsides like persistence and the size of containers have strategies to minimise their impact.</p>
<p>I would be very interested to hear your thoughts and experiences with microservices and containerisation.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Lessons from virtualising local development environments</title>
    <link href="https://blog.david-jensen.com/lessons-from-virtualising-local-development-environments/"/>
    <updated>2015-04-19T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/lessons-from-virtualising-local-development-environments/</id>
    <content type="html"><![CDATA[
      <p>While working at <a href="http://andigital.com" title="ANDigital">ANDigital</a> we used multiple languages/frameworks/web servers for both internal projects and external client work. Our goal was to be able to continuously deploy each of the services that we were involved with. I came to the conclusion that scripted virtualisation for local development put us on the right track to achieving this goal. The below outlines my learning from getting this process working.</p>
<h2>Vagrant wrapped VirtualBox for local virtualisation</h2>
<p>Vagrant is a handy wrapper for VirtualBox which allows you to programmatically setup underlying OS, mapped drives and define provisioning scripts. It also configures your local networking so you can see it as localhost. This can be checked into to your source control for ease of distribution as well as inbuilt change control.</p>
<h2>Ansible for provisioning</h2>
<p>Ansible is a configuration management tool that connects via SSH and programatically runs scripts for you. You use a simple language to define what each step will do and has default helpers for a lot of different tools such as Docker. The great thing about Ansible is that you can use it for both provisioning of servers and deployment of code. This is also checked in to a repository for distribution and change control.</p>
<h2>Same scripts locally and at all stages</h2>
<p>The advantage of using Ansible is that you can utilise very similar scripts for provisioning across every environment. The task based approach allows you to construct subtle differences but increases confidence of consistency. Automation of deployment also helps ensure that from your local environment through each stage that code lives in the same places executed in the same way.</p>
<h2>Package, build and tests management</h2>
<p>Ensuring that your development machine has the correct versions of packages, build and test tools can be quite a challenge. Especially when working on multiple projects with subtle differences. Having a script that configures these takes away a lot of the upfront setup and ensures you are running the same versions as your continuous integration servers.</p>
<h2>It works on my machine</h2>
<p>This is a such a common cry from developers and something we are slowly moving away from. As our local servers run a VM which is almost identical to development and production testing locally is much more realistic. It also forces developers to consider that there code will be running on a server. This is an important mindset that helps move away from this issue.</p>
<h2>My IDE does that for me</h2>
<p>The main pushback I have encountered is from people using a fully fledged IDE which contains a web server. I think that these two approaches can work in tandem which a push to your local server before checking code in as an extra step. I have also put an IDE within the server for an even higher level of consistency.</p>
<h2>Cost and productivity boosts</h2>
<p>The quicker that you can find a problem the easier and cheaper it is to solve. The lack of context switching required as you are awaiting feedback from test and regression is also a real bonus. No longer can it be the operations teams responsibility to push code to production, developers should comprehend the impact that their code makes on all environments and local virtualisation really helps this mindset. Being able to switch between different environments with a simple vagrant up is definitely a future I want to be part of.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>What 275 days of intensive care taught me about managing complex projects</title>
    <link href="https://blog.david-jensen.com/275-days-intensive-care-taught-managing-complex-projects/"/>
    <updated>2015-03-05T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/275-days-intensive-care-taught-managing-complex-projects/</id>
    <content type="html"><![CDATA[
      <p>For 275 days after his birth my son Jack lived in the intensive care units of various London hospitals. A large team of consultants, doctors, nurses and cleaners worked together 24/7 to support Jack's daily needs whilst solving his long term health problems. Managing complex projects is a large part of my job so being a geek I couldn't help but analyse the key mindsets and approaches that positively contributed to <a href="https://www.youtube.com/watch?v=37AMtPWhPiY" title="Jack's Journey">Jack's journey</a>. I believe that the concepts below can be applied to managing any complex long term problem and I hope you find them useful.</p>
<h2>Set the right long term goal to give context to all decisions</h2>
<p>In Jack's case this was the ability for him to go to a normal school without any assistance. This context provided assistance to making harder short term decisions.</p>
<h2>Complex questions rarely have a 100% answer</h2>
<p>Doctors are rarely able to give you a 100% answer to complex questions. I have come to appreciate this way of thinking as it avoids setting you up for disappointment. This reflects the reality of the unknown and changable nature of environments.</p>
<h2>The more people involved the harder consistent communication becomes</h2>
<p>Communication between all of the parties involved in 24/7 care is a constant challenge. This can be helped by writing things down, putting them on walls and doing as much as possible face to face.</p>
<h2>Start from the worst case scenario and work backward</h2>
<p>Planning for the worst ensures you really think about all options. This is a great mind hack to be happier with outcomes that aren't the best case scenario.</p>
<h2>Capture as much information as possible</h2>
<p>Over longer periods of time it is essential to write down decisions and observations so anyone can revisit the context and data around decisions if they weren't involved in them at the time.</p>
<h2>Establishing baselines and thresholds help autonomous decisioning</h2>
<p>Every baby is unique and collecting data is a great way to understand their current state compared to their history. Once you have established a baseline it is easier to empower people to act if thresholds are broken. Overall population baselines are also useful over a longer term view.</p>
<h2>Monitoring should be visual and constant</h2>
<p>All monitors should be highly visible and when something deviates from the established baseline then they should alarm. Alarms should have clear levels between their various states.</p>
<h2>Daily stand ups are essential</h2>
<p>A daily conversation with all of the people that are going to be involved in the care of the child are essential. This coupled with data enables distributed decision making. Face to face conversation ensures everyone gets the chance to contribute.</p>
<h2>Choosing the right option when many are available is difficult</h2>
<p>There is a decent amount of trial and error in solving complex problems. There are standard approaches which give you options for the next step but only by trying and measuring will you actually find out how effective they are.</p>
<h2>A clear path of escalation is essential</h2>
<p>Knowing who to ask if you are blocked or have an emergency is essential. This coupled with having access to people with greater levels of experience can really help move things forward. The last 8 months have been an incredible journey and I am unbelievably grateful for everyone who has helped us along the way. This process has broadened my approach, understanding and mindset for managing complex projects. I am thankful to the systems that have enabled Jack to have the smile that now warms my heart on a daily basis.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Scarcity and the trap of the daily deadline</title>
    <link href="https://blog.david-jensen.com/scarcity-trap-daily-deadline/"/>
    <updated>2014-11-07T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/scarcity-trap-daily-deadline/</id>
    <content type="html"><![CDATA[
      <p>For the past four years I have been working in an editorial environment Metro, the third largest daily UK newspaper. Over this time I have been amazed at the number of times that serious change has been attempted and failed. This seems to be a common problem with newspapers. Initially it confused me as there are a lot of very clever, passionate and motivated individuals involved. Over time however I have come to believe that there are three main components behind this. Having to fill a set number of pages by a daily deadline creates scarcity of time. The focus required to achieve this creates tunnel vision that both helps and hinders. It helps editorial climb their daily mountain but the bandwidth tax of doing this reduces their cognitive capacity for change. This theory formed after reading Scarcity by Sendhil Mullainathan and Eldar Shafir. The Guardian <a href="http://www.theguardian.com/books/2013/sep/07/scarcity-sendhil-mullainathan-shafir-review" title="Guardian review Scarcity">review</a> sums up the main premise of the book well:</p>
<blockquote>
<p>&quot;Scarcity captures the mind,&quot; explain Mullainathan and Shafir. It promotes tunnel vision, helping us focus on the crisis at hand but making us &quot;less insightful, less forward-thinking, less controlled&quot;. Wise long-term decisions and willpower require cognitive resources. Poverty (the book's core example) leaves far less of those resources at our disposal.</p>
</blockquote>
<p>The editorial process is driven by risk aversion, due to a lack of ability to change a printed product after the deadline. Banks of subs check and recheck work and a single person runs each section as well as an overall editor. These create multiple bottlenecks which adds significant overhead, coupled with low levels of autonomy which increases the queuing further. Most of the paper remains a work in progress until the last possible minute. Many of the systems that enable editorial processes are very old and not built for the current world we live in. Complex to change and expensive to run, this is the final piece holding back progress. Change requires running multiple concurrent systems. Each of these is tightly coupled with other complex systems and risk aversion is high. Cost to achieve this change is very high in monetary terms, training and complexity. Complex process coupled with complex systems and a reduced cognitive capacity for anything outside of their deadline has been holding back editorial progress for years. I believe this is one of the reasons why newer entrants without this legacy have fared so well. They don't have any of these previous constraints. Change is possible but usually underestimated due to the multiple layers of complexity and need to continue the existing process whilst building the new one.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>21 product development tips from the trenches</title>
    <link href="https://blog.david-jensen.com/21-product-development-tips-from-the-trenches/"/>
    <updated>2014-11-05T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/21-product-development-tips-from-the-trenches/</id>
    <content type="html"><![CDATA[
      <p><a href="https://www.flickr.com/photos/cobaltfish/8988013300">Trenches</a> by <a href="https://www.flickr.com/photos/cobaltfish/">Andy Rogers</a> | <a href="http://creativecommons.org/licenses/by/2.0/">CC BY</a> Over the past four years at Metro we have delivered one replatform, four redesigns, multiple native apps and built and sold an online casino. From these experiences we have iteratively built a process and environment that aids product development. An Agile mindset has helped the development team achieve a consistent output. This coupled with Lean thinking delivered growth that convinced the business to fully embrace our process. The below are 21 product development tips that were hewn in the trenches of failure we call learning.</p>
<h2>1: Ensure everyone has a clear vision of the end goal</h2>
<p>This needs to be concise, measurable and most importantly achievable. A strong reason behind why that goal was chosen will help motivation. Everyone should be clear on what they can do to affect the goal. This should be the main job of leadership.</p>
<h2>2: Use small cross functional, self organising teams</h2>
<p>Should have as much <a href="http://vimeo.com/album/3107510/video/110550974" title="Spotify Agile">autonomy</a> as possible in how they affect their goal. This is key to enabling faster decision making which increases learning velocity. Proximity is the best hack to maximise face to face communication. This is the most effective way to ensure a common understanding.</p>
<h2>3: Timing is everything</h2>
<p>The biggest challenge is building the right product/feature, at the right time, using the right technology. The biggest waste is building things that people don't want or need now.</p>
<h2>4: Focus on figuring out the next releasable step that takes you closer to your goal</h2>
<p>Ensure it is small, releasable and gets you both closer to your goal and provides valuable feedback.</p>
<h2>5: Prototypes are a great way to improve early and ongoing feedback</h2>
<p>Paper/whiteboards are a great place to start as they allow the quickest iteration. Later prototypes are most effective when viewed in the medium they will be delivered in e.g. In browser/device.</p>
<h2>6: Project plans should as high level as possible</h2>
<p>They are great for making a high level view of major deliverables visible. If they constantly need updating they are too granular.</p>
<h2>7: UX/Design should be 2-4 weeks ahead of development</h2>
<p>Designing and building prototypes with a goal of getting as much feedback as possible before development begins.</p>
<h2>8: What is designed and what is built are two separate things</h2>
<p>Both should inform the other but there is no master due to constraints on both sides.</p>
<h2>9: Just in time is the best approach to detailed planning</h2>
<p>Any earlier can be <a href="http://cf.agilealliance.org/articles/system/article/file/1007/file.pdf" title="Just In Time Planning">wasteful</a> due to risk of new data from earlier releases or prototypes. Pair up on ticket writing using face to face communication and attach any prototypes/mockups/wireframes.</p>
<h2>10: Less is more with process once you have a mature team</h2>
<p>An agile journey must start somewhere and a fixed process like <a href="http://www.infoq.com/minibooks/scrum-xp-from-the-trenches" title="Scrum from the Trenches">Scrum</a>/<a href="http://www.crisp.se/file-uploads/Lean-from-the-trenches.pdf" title="Lean from the Trenches">Kanban</a> is a great place to begin. However as the team and process matures your aim should be to reduce this to the minimum possible for your environment.</p>
<h2>11: Centralised communication is best done outside of email</h2>
<p><a href="https://slack.com" title="Slack">Slack</a>/<a href="https://trello.com" title="Trello">Trello</a> are great examples of products that allow a participatory conversation without the cognitive overload of email.</p>
<h2>12: Evolutionary architectural approach works best, complexity shows where work is needed</h2>
<p>The simpler you start the quicker you can get real feedback. Avoiding <a href="http://www.ibm.com/developerworks/library/j-eaed1/" title="Evolutionary Architecture">over architecture</a> allows you to combat scaling issues when required, usually by following established patterns. This avoids adding unnecessary complexity early on which can seriously hamper your ability to learn fast.</p>
<h2>13: Micro services are a great pattern for a service based architecture</h2>
<p>The ability to pick up, modify and release a service with complete confidence that it won't impact anything else helps you move faster. They also allow you to prototype new technologies in a production environment. Focus on <a href="http://www.infoq.com/articles/microservices-practical-tips" title="Microservices Tips">automation</a> up front to minimise overheads of running multiple services.</p>
<h2>14: Focus</h2>
<p>The less we build the better we build what we do. Cognitive overload of working on multiple things at a time has a huge impact on quality.</p>
<h2>15: Limiting work in progress is the best way to speed up delivery</h2>
<p><a href="http://scrumandkanban.co.uk/littles-law/" title="Littles Law">Queues are very ineffective</a>, the more queues you have and the more items they contain the worse they perform.</p>
<h2>16: Product feedback should happen on a regular basis and have all stakeholders attend</h2>
<p><a href="http://www.fastcompany.com/3027135/lessons-learned/inside-the-pixar-braintrust" title="Pixar Brain Trust">Feedback</a> should be constructive, open and honest. As we release everyday we have two demos a week and our Slack channel is constantly open for feedback. This is where work is prioritised, discussed and tweaked.</p>
<h2>17: Data wins arguments</h2>
<p>It's ok to loose a battle based on opinion to come back and win the war with data. Make sure you are measuring the right things, this takes time but is worth the investment. Then look for anomalies or what I call &quot;data smells&quot;. Following these to their cause will give you great insight into your product.</p>
<h2>18: Innovation needs time and space to happen which initially needs to be forced</h2>
<p>Hacks days/afternoons are a great way to kick start this process. Give people the a fixed time with a clear direction and see what they come up with.</p>
<h2>19: Beware of the curse of knowledge</h2>
<p>Don't get frustrated, embrace the fact that some people aren't as far along the journey as you and help them take those next steps.</p>
<h2>20: People should have strong opinions that are weakly held</h2>
<p>An opinion is always useful to speed up the ideation phase. Logic around environmental constraints should shape the final decision.</p>
<h2>21: Embrace your constraints</h2>
<p>Each environment has a unique set of constraints. Use these to aid quick decision making. This should give you time to focus on what you need to change long term to be most effective.</p>
<p>During my time at Metro the only constant was change. We were able to embrace this and use it to our advantage. Iterative learning based approaches helped us maintain consistent growth. Delaying every decision until we had the best data possible kept our failures small and valuable. Building great products is about forming a team around an achievable goal and iterating based on the best feedback available at each stage.</p>
<p><strong>Evolution of the Metro.co.uk homepage over the past four years</strong></p>
<div class="gallery">
<a href="#g4-0"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-1.jpg" alt="" /></a>
<a href="#g4-1"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-2.jpg" alt="" /></a>
<a href="#g4-2"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-3.jpg" alt="" /></a>
<a href="#g4-3"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-4.jpg" alt="" /></a>
<a href="#g4-4"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-5.jpg" alt="" /></a>
<a href="#g4-5"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-6.jpg" alt="" /></a>
<a href="#g4-6"><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-7.jpg" alt="" /></a>
</div>
<div id="g4-0" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-6" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-1.jpg" alt="" /><a href="#g4-1" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g4-1" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-0" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-2.jpg" alt="" /><a href="#g4-2" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g4-2" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-1" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-3.jpg" alt="" /><a href="#g4-3" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g4-3" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-2" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-4.jpg" alt="" /><a href="#g4-4" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g4-4" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-3" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-5.jpg" alt="" /><a href="#g4-5" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g4-5" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-4" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-6.jpg" alt="" /><a href="#g4-6" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g4-6" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g4-5" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/21-product-development-tips-from-the-trenches/metro-7.jpg" alt="" /><a href="#g4-0" class="lightbox-nav lightbox-next">&#8250;</a></div>

    ]]></content>
  </entry>
  
  <entry>
    <title>How software ate manual content placement on Metro.co.uk</title>
    <link href="https://blog.david-jensen.com/how-software-ate-manual-content-placement-at-metro/"/>
    <updated>2014-10-27T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/how-software-ate-manual-content-placement-at-metro/</id>
    <content type="html"><![CDATA[
      <p>The majority of content placement on <a href="http://metro.co.uk" title="Metro">metro.co.uk</a> is now managed by software. This has been a long journey based on real world feedback and incremental addition of complexity. My goal has always been to take a developer's view of the editorial process and optimise where possible. Looking at the numbers it became clear that for large areas of the site a disproportionate amount of time was spent on content placement for the value it returned. My previous post covered the <a href="/metro-newsfeed-algorithm-works/" title="Metro Newsfeed Algorithmn">first part of the journey</a> and now I will explain how we extended this to run the majority of the site. We gather a lot of information from WordPress, Facebook, Twitter and Omniture into a MySQL database. This data is passed through a stored procedure to return five different sorts:</p>
<h2>Score</h2>
<p>((Tweets + Facebook Interactions) * Social Multiplier) + Views</p>
<h2>Trending</h2>
<p>Score Now - Score 30 Mins Ago</p>
<h2>Social</h2>
<p>Tweets + Facebook Interactions</p>
<h2>Date</h2>
<p>Date descending</p>
<h2>Coefficient</h2>
<p>((((Tweets + Facebook Interactions) * Social Multiplier) + Views + Editorial Boost) * Hour Coefficient) + Tag Boost</p>
<p>We also pass in the following to modify the results depending on the channel, e.g. news, that the data sits within.</p>
<h2>Hours to return</h2>
<p>e.g. From 24-336 since publishing</p>
<h2>Filter Subcategories</h2>
<p>e.g. Football,Oddballs,Weird,Food</p>
<h2>Boost Tag</h2>
<p>e.g. arsenal-fc</p>
<h2>Social Multiplier</h2>
<p>e.g. 10</p>
<h2>Content Type</h2>
<p>e.g. Blog or Post</p>
<h2>Remove Tags</h2>
<p>e.g. tottenham-hotspur-fc</p>
<h2>Coefficient</h2>
<p>e.g. 0-4 * 3, 4-12 * 1. 13-24 * 0.5, 25-48 0.3</p>
<p>The coefficient sort now takes input from the articles that the editors place at the top of each of the channel pages of the site. This editorial boost allowed us to keep everything feeling much fresher until the data catches up. We have also built our own real time page view tracking system with Node and Redis to get around the time lag in Omniture of 30-60 mins. We recently centralised all of the settings so that they are easy to view and change. I focused on optimising the cluster of content returned and timeframes to retrieve within to get them working with publishing patterns per channel. The ability to cluster content of similar channels has helped ensure we offer a wider variety of content at different stages of the user's journey. Using different sort methods coupled with this clustering has reduced duplication. The design has also helped by using different image ratios and colours for different sections of that page that may contain the same content. We have standardised the bottom of all pages to be the same. This means if we are able to improve performance then it is felt across the entire site. The last addition was the ability to boost by tag. This has enabled the article based algorithm to be much more relevant. At this level of granularity we decided context is much more important than freshness. Moving the tag boost outside of the coefficient enabled this to be clustered at the top but we limit this to the five most recent related articles. Our API is able to deliver everything that the front end needs for rendering including title, image and excerpt. This has also enabled us to use this data in multiple places such as the native Tablet and Phone Editions and the glance journalism experiment Metro10 and MetroVision. Our feeds finally go through an additional layer that allow us to add sponsored content at fixed positions for traffic driving purposes. The great part of all of this is that the maths is still very simple and can be explained to anyone who is interested. Having a set of values to tweak per channel has enabled us to have enough options to slice the data for use in multiple contexts. It has taken 12 months and a full redesign to really see this come to life but I hope it will be a part of Metro for years to come.</p>
<h2>Home Page</h2>
<p><a href="/assets/images/how-software-ate-manual-content-placement-at-metro/home-order-coefficient-latest.jpg"><img src="/assets/images/how-software-ate-manual-content-placement-at-metro/home-order-coefficient-latest.jpg" alt="Metro Homepage Placements"></a> Metro Homepage Placements</p>
<h2>Article Page</h2>
<p><a href="/assets/images/how-software-ate-manual-content-placement-at-metro/article-order-coeff.jpg"><img src="/assets/images/how-software-ate-manual-content-placement-at-metro/article-order-coeff.jpg" alt="Metro Article Page Placement"></a> Metro Article Page Placement <strong>My talk at the WordPress VIP Big Media <a href="http://vip.wordpress.com/2014/05/21/metro-uk-content-algorithm/" title="Metro Content Algorithm Talk">Meetup</a> on this.</strong></p>

    ]]></content>
  </entry>
  
  <entry>
    <title>21 product guidelines forged while growing Metro.co.uk 400%</title>
    <link href="https://blog.david-jensen.com/21-product-guidelines-growth-hacking-metro-co-uk-4x/"/>
    <updated>2014-10-13T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/21-product-guidelines-growth-hacking-metro-co-uk-4x/</id>
    <content type="html"><![CDATA[
      <p>For the last two years I have been focused on the design, build and growth of Metro.co.uk utilising the WordPress VIP platform. Our approach consists of constant experimentation with both product and content which has returned a large set of data mixed with editorial feedback. This has been refined into a list of product guidelines to help us remain focused on growth. These are based on my experiences and our audience so yours may differ.</p>
<h2>1: Good editorial content will deliver more growth than any product based approach</h2>
<p>With a single well written/planned/timed story able to deliver millions of page views and course through the veins of social networks for weeks this should be the number one focus.</p>
<h2>2: Good UX turns the dial more than any product hacks</h2>
<p>The better the experience of product and content the more likely people are to visit your site, share your content and form habits around its consumption.</p>
<h2>3: The closer to the main content area of the page the more related the content should be</h2>
<p>Our data has shown that the closer to the article body or top of channel pages the better contextually related content perfoms. Once you are below these areas users are more open to a wider set of content to continue their journey.</p>
<h2>4: Where content is placed on the page is almost as important as the content that is placed there</h2>
<p>Our testing revealed content placement is almost as important as content selection (as long as it is relevant and recent). This is one of the reasons we have moved to an algorithmic approach for large areas of the site.</p>
<ul>
<li>Nothing beats the value of an editorially selected contextual link within the article body</li>
<li>The area just after article delivers a lot of value as users have finished reading and can be easily tempted into something else</li>
<li>Sidebars aren't shown on mobile and banner blindness often turns them off for desktop users so they are not an area we focus on</li>
</ul>
<h2>5: Fill dead space with content, people like to scroll it's the natural behaviour of the web</h2>
<p>Our newsfeed delivers over 10% of the page views of our site, this is pretty impressive considering it used to be blank space at the bottom of every article and channel page.</p>
<h2>6: Don't mess with the natural way that the web works</h2>
<p>We tried and failed with this during our <a href="http://metro.co.uk/2013/10/01/why-swipe-has-been-removed-from-metro-co-uk-and-what-the-future-holds-4110488/" title="Swipe Fail">swipe phase</a>. 5-7% of users delivered 20% of our page views but that didn't increase their overall time on site. However it complicated everything we built hampering our ability to learn fast. It also didn't quite fit into commercial or editorial strategies. This frustration/learning was what inspired the algorithm and scroll based newsfeed you now see.</p>
<h2>7: Algorithms are great but need help from humans to perform at their best</h2>
<p>Simple algorithms are a great way to optimise editorial workflows especially around content positioning. However these are only as good as the data behind them. Often you have to wait for this to be gathered before acting on it. Using editorial intuition is a great way to shortcut this process. Especially if you can make it run off existing priorities then process change isn't required to participate.</p>
<h2>8: Whatever Google/Facebook ask you to do just do it</h2>
<p>They deliver so much of your traffic don't question, just do what they recommend.</p>
<h2>9: Feed the beast</h2>
<p>Google and Facebook are always hungry for quality content. Gaining momentum requires constant feeding. They both have overall scores for domain as well as article urls so focusing on keeping this high means a better chance to gain and then maintain momentum.</p>
<h2>10: Think of every page as a funnel, you loose users as they scroll but the lower they get the more open to their next engagement they become</h2>
<p>The higher up the page something is placed the more people will see it. However the lower down the page someone is the more open they are to being tempted by some more content, advertising or interactions (e.g. poll vote, comments)</p>
<h2>11: A mobile first approach is a great way to approach product prioritisation</h2>
<p>Most of our traffic comes from mobile rather than desktop so it is logical to prioritise. This has formed a major part of our growth strategy.</p>
<h2>12: Goals need to be concise, measurable and focus on why</h2>
<p>The more people understand the goal and are able to affect it the more powerful it is. A goal that contains a why will always beat a goal that just contains a what.</p>
<h2>13: Product specific performance should be broken down to actions per daily active users for comparison</h2>
<p>This gives a much better overview of actual performance. Allows you to take out traffic fluctuations, just make sure you have enough data.</p>
<h2>14: A week seems to be the minimum amount of data required to see if a feature has worked</h2>
<p>Due to fluctuations in traffic and browsing habits. Also good to look at monthly and quarterly trends over longer periods as quite often they exhibit patterns that aren't found at lower levels. It was asking questions around unexpected trends/data that helped teach me most around product growth.</p>
<h2>15: Distribute weekly reports to show trends and give your stakeholders an overview of how the product is performing</h2>
<p>Have these scheduled to your team and stakeholders via email. Also very useful if you break something when fixing something else. Great safety net to minimise impact and spot any unexpected growth.</p>
<h2>16: Any new feature needs to be taken in context of how it fits in the editorial work flow. The closer it is to the existing process the more likely it will be adopted.</h2>
<p>The best way to change a habit is build off an existing trigger. New features that leverage existing habits will get much higher adoption than building new habits/process.</p>
<h2>17: Consider the users current journey and their emotional state in all features</h2>
<p>Segmenting users based on mindset is a great way to understand data. e.g. Social browsers are likely on a multi site journey in a chromed browser on a mobile device. So they are only looking for a single story from your site so optimise for that. No point in worrying about pages/visit focus on getting more return visits via a social follow.</p>
<h2>18: When coming from social users are often looking to enhance their social status</h2>
<p>Our top share buttons get clicked on 4 times more than our bottom share buttons. Social proof around number of others already shared also promotes more sharing.</p>
<h2>19: When coming from search users are usually in a topic based mindset</h2>
<p>More likely to click on related, in article links and masthead channel links. Continue to deliver great content around a niche to form habits. Particularly useful around passion centres e.g. Premier League clubs.</p>
<h2>20: It's better to have 100 amazing tag pages that look and feel like a destination than 10,000 that feel like they were made for Google</h2>
<p>Quality trumps quantity every time, Google knows if you users are clicking through.</p>
<h2>21: People click on headlines 4x more than they click images</h2>
<p>This is why A/B testing headlines is a great idea. It is the single piece of the editorial process that can have the biggest impact on growth. We also have SEO and socially optimised headlines to ensure we cater to both needs. These are the principles that I have applied to the product development of metro.co.uk over the past two years. The key takeaway is that constant experimentation is a great way to unlock growth if your environment supports it. The hard part is achieving that without adding too much complexity. Complexity inhibits your ability to learn and learning is central to any successful product growth strategy. Building a set of guidelines has enabled us to move faster and helped foster our continued growth. One for the future.</p>
<h2>Micro interactions help drive habitual use</h2>
<p>We don't have a lot of data on this yet but there seems to be a correlation between micro interactions such as poll votes and habitual use. My theory is that by engaging different parts of the brain you become more memorable. These simple actions form the basis of new habits around content consumption. I think this is a major opportunity for future growth.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>The thoughts and process behind Metro10</title>
    <link href="https://blog.david-jensen.com/thoughts-process-behind-metro10/"/>
    <updated>2014-09-30T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/thoughts-process-behind-metro10/</id>
    <content type="html"><![CDATA[
      <div class="gallery">
<a href="#g1-0"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4560.jpg" alt="" /></a>
<a href="#g1-1"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4561.jpg" alt="" /></a>
<a href="#g1-2"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4562.jpg" alt="" /></a>
<a href="#g1-3"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4563.jpg" alt="" /></a>
<a href="#g1-4"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4564.jpg" alt="" /></a>
<a href="#g1-5"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4565.jpg" alt="" /></a>
<a href="#g1-6"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4566.jpg" alt="" /></a>
</div>
<div id="g1-0" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-6" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4560.jpg" alt="" /><a href="#g1-1" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g1-1" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-0" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4561.jpg" alt="" /><a href="#g1-2" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g1-2" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-1" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4562.jpg" alt="" /><a href="#g1-3" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g1-3" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-2" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4563.jpg" alt="" /><a href="#g1-4" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g1-4" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-3" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4564.jpg" alt="" /><a href="#g1-5" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g1-5" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-4" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4565.jpg" alt="" /><a href="#g1-6" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g1-6" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g1-5" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/IMG_4566.jpg" alt="" /><a href="#g1-0" class="lightbox-nav lightbox-next">&#8250;</a></div>
<p>Metro 10 was born out of a desire to experiment with native mobile news reading experiences that solved a different problem to our already fully responsive website. We had an algorithm that allowed customisation and decided to use this as our data source. The concept of restricting the volume of content would help us differentiate from our infinite web experience. We also wanted our users to engage with each article fully before moving on and not just get into a state of skimming which we had seen with infinite lists online.</p>
<p>Our goal was to minimise the time to launch so we decided a hybrid approach would help this. Utilise the native elements for caching and navigation but a web view for the article body. As our CMS stores all of the HTML and other markup in a single blob stripping this out was too much work for the first iteration of an idea that was unproven. Our initial ideas were based on simple mobile interaction patterns. Swipe to dismiss, interaction based personalisation and full bleed images as our tablet edition had experimented successfully with this. We decided on an Android first approach as we had Java skills in house and we also wanted to iterate quickly once it had launched. The turnaround in the Play store would allow us to do this.</p>
<p>I hadn't written any code in four years and getting back in the saddle was a rewarding experience. Leaning a new language and platform at the same time took a little time but the tools and ecosystem are pretty mature. Initially I got out my little black Moleskin notebook and started sketching. Putting something down on paper helped me to start to visualise flow and basic function. I am no UX designer but I find sketching a really valuable first step in any design process.</p>
<p>Once we had a basic idea we jumped into a rapid prototyping phase. This involved a lot of copying and pasting from Stack Overflow and some working from home to get some focus to get the bare bones of an app together. It was buggy as hell but being able to show people on a phone and see there reaction was priceless. I then involved Matt our UX designer and he started to iterate on the design. We were lucky that the concept was simple and allowed very quick iterations. The design quickly morphed from a list that looked very web based to a full bleed image that felt more mobile first.</p>
<p>It was at this stage I got a few more of the team involved. When rapid prototyping it was good to be solo and really iterate quickly but once we were locked on an idea we needed stability and to start on a refactoring process to move towards a proper architecture. I believe in emergent design where you don't over architect things up front but as you learn more of the systems and domain build what is most appropriate. This can save a lot of time as you only build what is necessary and refactor once you are sure of its value.</p>
<p>The next phase of development to our first alpha was frustrating at times but also very rewarding. We kept the requirements process very fluid as things would change on a daily basis. This was a challenge but having written user stories which were quickly out of date and fought with automation of testing we decided keeping things simple was the best approach. Guerrilla usability testing has been key to shaping the UX. As the initial idea was pretty out there putting it in real peoples hands in the real world was priceless. We quickly learnt that people liked the limited number of stories, enjoyed the full screen design but having to dismiss every story Snapchat style wasn't something that they felt comfortable with. The paradox of choice was blinding them. With 10 possible stories to read and only one visible at a time and only one chance to read it they couldn't decide whether it was interesting enough.</p>
<p>We decided to strip the user experience back to its most basic and only give people 10 stories at at time that they can scroll through left and right. With this approach people were quickly able to grasp the concept and understand the navigation. Calling it Metro10 ensured that we kept to our goal of just the 10 most popular stories right now. Throughout this process there have been a lot of tension between what constitutes our MVP. Due to a fixed timeframe we had to make some compromises around fluidity of design. The biggest was to leave all interactions via gestures rather than fluid animations. The level of complexity rose exponentially with these.</p>
<p>We were able to get validation of our ideas without them. Learning if the concept works is the most important and all of the underlying data, service and business layer need to work no matter what the front end looks like. Overall it has been a great experience in taking a concept from paper to reality in less than two months. There have been lots of zigs and zags along the way but that is what makes this job interesting.</p>
<h2>MVP</h2>
<div class="gallery">
<a href="#g2-0"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/1-Metro-Android-App.jpg" alt="" /></a>
<a href="#g2-1"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/2-Metro-Android-App-Journey.jpg" alt="" /></a>
<a href="#g2-2"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/3-Metro-Android-App-v2.jpg" alt="" /></a>
<a href="#g2-3"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/4-Metro-Android-App-v3.jpg" alt="" /></a>
<a href="#g2-4"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/5-Android-Screens.jpg" alt="" /></a>
<a href="#g2-5"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/6-Metro-Android-App-First-And-Last-Screens.jpg" alt="" /></a>
<a href="#g2-6"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/6-Metro-Android-App-Instructions.jpg" alt="" /></a>
<a href="#g2-7"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/7-Metro-Android-App-Logos.jpg" alt="" /></a>
<a href="#g2-8"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/8-Metro-Android-App-Instructions.jpg" alt="" /></a>
<a href="#g2-9"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/9-Metro-Android-App-UPDATED.jpg" alt="" /></a>
<a href="#g2-10"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/10-Metro-Android-App-UPDATED.jpg" alt="" /></a>
</div>
<div id="g2-0" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-10" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/1-Metro-Android-App.jpg" alt="" /><a href="#g2-1" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-1" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-0" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/2-Metro-Android-App-Journey.jpg" alt="" /><a href="#g2-2" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-2" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-1" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/3-Metro-Android-App-v2.jpg" alt="" /><a href="#g2-3" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-3" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-2" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/4-Metro-Android-App-v3.jpg" alt="" /><a href="#g2-4" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-4" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-3" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/5-Android-Screens.jpg" alt="" /><a href="#g2-5" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-5" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-4" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/6-Metro-Android-App-First-And-Last-Screens.jpg" alt="" /><a href="#g2-6" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-6" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-5" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/6-Metro-Android-App-Instructions.jpg" alt="" /><a href="#g2-7" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-7" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-6" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/7-Metro-Android-App-Logos.jpg" alt="" /><a href="#g2-8" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-8" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-7" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/8-Metro-Android-App-Instructions.jpg" alt="" /><a href="#g2-9" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-9" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-8" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/9-Metro-Android-App-UPDATED.jpg" alt="" /><a href="#g2-10" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g2-10" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g2-9" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/10-Metro-Android-App-UPDATED.jpg" alt="" /><a href="#g2-0" class="lightbox-nav lightbox-next">&#8250;</a></div>
<h2>Later iteration</h2>
<div class="gallery">
<a href="#g3-0"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Splash.png" alt="" /></a>
<a href="#g3-1"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Thumb.png" alt="" /></a>
<a href="#g3-2"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Articles.jpg" alt="" /></a>
<a href="#g3-3"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Personalise.png" alt="" /></a>
<a href="#g3-4"><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Settings.png" alt="" /></a>
</div>
<div id="g3-0" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g3-4" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Splash.png" alt="" /><a href="#g3-1" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g3-1" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g3-0" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Thumb.png" alt="" /><a href="#g3-2" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g3-2" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g3-1" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Articles.jpg" alt="" /><a href="#g3-3" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g3-3" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g3-2" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Personalise.png" alt="" /><a href="#g3-4" class="lightbox-nav lightbox-next">&#8250;</a></div>
<div id="g3-4" class="gallery-lightbox"><a href="#" class="lightbox-close">&times;</a><a href="#g3-3" class="lightbox-nav lightbox-prev">&#8249;</a><img loading="lazy" src="/assets/images/thoughts-process-behind-metro10/Metro10-Settings.png" alt="" /><a href="#g3-0" class="lightbox-nav lightbox-next">&#8250;</a></div>

    ]]></content>
  </entry>
  
  <entry>
    <title>Responsive Design and the Mobile First Mindset</title>
    <link href="https://blog.david-jensen.com/responsive-design-mobile-first-mindset/"/>
    <updated>2014-08-12T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/responsive-design-mobile-first-mindset/</id>
    <content type="html"><![CDATA[
      <p>Responsive design was a key enabler of the strategy that enabled Metro to grow to 34m monthly uniques. It put the end user first and ensured our content looked the best it could at the time of render. We worked from the mobile screen up to the desktop and this enabled us to make quick design decisions. Key principles like this are a cornerstone of rapid project delivery.</p>
<p>Changing the mindset of the business to make mobile a first class citizen was a big challenge. However once they had agreed on a mobile first paradigm we were able to tackle the hard questions up front and once this allowed the development team to focus on how best to approach the responsive elements.</p>
<p>Image resizing was a key part of keeping our file sizes low and having a fast perceptive render. We also dropped our custom font on mobile due to render speeds. An adopted an adaptive approach that only delivered the HTML necessary for the page to render and prioritised mobile for speed reasons.</p>
<p>Mobile first ensured we spent our time focussing on the main content that the user had come to read. We went for the simplest option of not including the sidebar of content on mobile as it would only add page weight. The volume of clicks in this area also justified it not being included. Users have a sidebar blindness and unless it is the main navigational feature will rarely get used as the brain turns it off to focus on reading the main content area.</p>
<p>We are currently going through a new redesign process which will give a new lick of paint to what we achieved two years ago but the principles remain the same.</p>
<p><strong>The below is a presentation delivered at the Google HTML5 Roundtable about Metro's journey into responsive design</strong></p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Ten things we learnt building the Android App Metro10</title>
    <link href="https://blog.david-jensen.com/ten-things-learnt-building-android-app-metro10/"/>
    <updated>2014-03-25T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/ten-things-learnt-building-android-app-metro10/</id>
    <content type="html"><![CDATA[
      <p>Metro10 is the first Android App that I have been involved in from concept to release in the Google Play store. It was designed, developed, tested and deployed in the first three months of 2014. We spent the entire process learning and here are details of 10 things that we learnt as part of the process.</p>
<h2>1 - To begin the pen is mightier than the keyboard</h2>
<p>Starting with a paper and a pen is a great way to iterate quickly through ideas. Sketches are one of the easiest forms of communication at this stage. There lofi form means you are usually more comfortable with changing them.</p>
<h2>2 - Keep the concept simple</h2>
<p>We went through many stages of adding complexity to Metro10 but we always came back to the simplest implementation. With the lack of space on a mobile screen and wide audience we intended to go for this was what kept redefining our approach.</p>
<h2>3 - Rapid Prototyping is your friend</h2>
<p>We managed to get a version on a phone within 3 days that had our initial concept on it. This helped us put it in front of a much wider set of people very early in the process. It didn't run off feeds, ran out memory quickly and had random image sizes but was key to getting a wider set of people giving us feedback on our concept.</p>
<h2>4 - Guerrilla usability testing is a great way to get early feedback</h2>
<p>As we had a prototype early I just started going up to people and giving it to them without any instructions. Watching their frustrations and listening to the questions they asked provided amazing feedback to help shape our product.</p>
<h2>5 - Image resource management on Android is not straight forward</h2>
<p>We probably spent close to half the time on the app stopping out of memory errors due to cropping and displaying of images. By making sure you manually clear the copy of the image that is attached to the image view we managed to fix this.</p>
<h2>6 - Do as much processing as you can on the server</h2>
<p>We ended up using the WordPress image resizer to resize all of our images to the specific screen size before they got to the device. This helped speed up processing and ensured we only downloaded the image size we needed.</p>
<h2>7 - 7&quot; tablets are actually treated as large phones</h2>
<p>Android treats 7&quot; tablets as very large phones rather than small tablets. This can mean your app needs some adjustment to look good on the larger screen.</p>
<h2>8 - Google Play Store Alpha and Beta Communities are the best use for Google+</h2>
<p>Google allow you to set up a community on Google+ which will give pre-release access to members. This was a great way to get feedback and manage the roll out of the app. It really made this part of the process a pleasure.</p>
<h2>9 - Unit testing and front end automation for repeatable testing</h2>
<p>We used both JUnit tests and front end automation to quickly get feedback on every change. We moved away from the Android unit tests due to speed issues with the emulator. We managed to integrate those and the front end framework with our CI environment though the management of emulators again provided some interesting challenges.</p>
<h2>10 - There is no substitute for using real devices in testing</h2>
<p>Emulators provided a great way for us to get started quickly but using a mouse to control features proved tricky. We also saw different behaviour on emulators and real devices over the time period. The best way to learn something is by doing it, by starting with a set of constraints and a focus on simplicity and I am very happy with the results we got with Metro10. We have now passed 500 downloads, are maintaining over 100 daily active users and still have over a four star rating.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How the Metro.co.uk Newsfeed Algorithm Works</title>
    <link href="https://blog.david-jensen.com/metro-newsfeed-algorithm-works/"/>
    <updated>2014-03-10T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/metro-newsfeed-algorithm-works/</id>
    <content type="html"><![CDATA[
      <p>We have been working on automating large parts of the content ordering on Metro.co.uk since our responsive redesign in Dec '12. This has grown from managing a few widgets across the site to controlling the majority of the homepage. The below describes the process we went through to achieve this. The first step was to get data out of its separate repositories and in a place that allowed manipulation. We began to collect page views and social interactions from APIs provided by Twitter, Facebook and Omniture into a MySQL database. The basic initial equation we used to figure out what was popular was:</p>
<h2>Popular = ((Tweets + Comments + Likes + Shares) * 25) + Views</h2>
<p>We decided to give the social signals a significant multiplier as a share action gave a much stronger signal of how much the content was liked than a page view. Based on this thought process we started with a very high multiplier of around 50 but reduced this to 25 after looking at the results over a period of time. This was calculated every half hour after fresh data was collected. The main issue with this approach was the frequency of change within the top stories. So we changed ordering to be based on the rate of change between the previously calculated score. We called this trending and it gave a really interesting snapshot of what was popular on the site and this improved the frequency of change.</p>
<h2>Trending = Popular Score (Now) - Popular Score (30 minutes ago)</h2>
<p>When we redesigned the site this sat right below the top five stories on the homepage. When we check the stats we were surprised that the number of clicks were almost identical to the clicks on the top module that were editorially selected and also had very large clickable images. Clearly people were interested in what other everyone else was interested in. This data also proliferated across our sidebars and into our Tablet and Phone Editions via an API. It updated 24/7 and required no manual intervention so no matter what time you visited the site it displayed a mix of fresh popular content. Based on the numbers we decided to see if this could be extended to run more of the site.</p>
<p><img src="/assets/images/metro-newsfeed-algorithm-works/Home-Zone-1024x734.png" alt="Home Page Top Five Stories (Editorially Chosen)"></p>
<p><img src="/assets/images/metro-newsfeed-algorithm-works/Home-Zone-Clicks-1024x569.png" alt="Weekly Clicks On Top Five Stories on Homepage"></p>
<p><a href="/assets/images/metro-newsfeed-algorithm-works/whats-trending-now.png"><img src="/assets/images/metro-newsfeed-algorithm-works/whats-trending-now.png" alt="Home Page Top Five Trending Stories (Algorithmically Chosen)"></a></p>
<p><a href="/assets/images/metro-newsfeed-algorithm-works/Home-Trending-Click.png"><img src="/assets/images/metro-newsfeed-algorithm-works/Home-Trending-Click-1024x558.png" alt="Clicks on Top Five Trending Stories on Homepage"></a></p>
<p>One of Metro's competitive advantages is that it runs a very lean digital operation. We want people to spend their time finding and writing great content rather than worrying about placement. A relatively small volume of our traffic goes to our channel pages (e.g. News) or looks at sidebars due to the volume of mobile traffic we pull in. So we decided to experiment further with this concept and get it to run the rest of the homepage. We had placed a timebased feed at the bottom of the homepage and had been very surprised with the number of interactions. Just being time based wouldn't work for the homepage as we needed a measure of popularity, freshness and time. I sat down last December and started prototyping approaches to take. We had to give new stories a chance to be featured before they had as much data. We also didn't want one huge story to be at the top for too long. After much deliberation/time spent running around Hyde Park I decided I would use a coefficient based on story age to boost posts in the early stages and penalise them once they had been live long enough to have an unfair advantage.</p>
<h2>(Views + (Social * 25)) * Hours Since Published Coefficient</h2>
<p>Hours Since Publish</p>
<p>Coefficient</p>
<p>0</p>
<p>25</p>
<p>1</p>
<p>15</p>
<p>2</p>
<p>5</p>
<p>3</p>
<p>3</p>
<p>4</p>
<p>1</p>
<p>4-8</p>
<p>0.7</p>
<p>9-12</p>
<p>0.3</p>
<p>13-24</p>
<p>0.05</p>
<p>25-36</p>
<p>0.02</p>
<p>We had also been talking about how we could distribute content around the site better. Especially at the bottom of articles as this is where the majority of our traffic comes. This is when we placed the same timebased feed from the homepage underneath every article in what used to be empty space. We were amazed once again at the level of interaction this received and decided to optimise the data behind it.</p>
<p><img src="/assets/images/metro-newsfeed-algorithm-works/Timeline-Interactons-1024x718.png" alt="Additional Pages of Data Pulled In Via Lazy Load for Timeline (Weekly)"></p>
<p>The main idea was rather than restricting the stream to just articles from the specific sub-category (e.g. Sport/Football) you were in, we could use the highest level category and boost the subcategory you were in. Eg see all of Sport but have all Football stories closest to the top. This would give other very popular sports stories a place as well as aiding circulation around the site.</p>
<h2>(Current Channel Boost + Views + (Social * 10)) * Hours Since Published Coefficient</h2>
<p>I then added an option to allow you to pass in the channels that a user visited the most and using the same logic to prioritise their content near the top. Again not excluding content but rather ordering it in a way that was most appropriate for the person viewing. This is going to form the basis of our new Android App with it just displaying the top ten stories based on your browsing habits.</p>
<h2>(Users Channels Boost + Views + (Social * 10)) * Hours Since Published Coefficient</h2>
<p>The final twist was to use the data that we had collected on the backend to style the front-end. Our News Feed now changes its imagesize depending on if a story is trending or has been flagged by editorial. This give prominence to the popular stories as the algorithm pushes them further down the list and keeps the styling changing 24/7. As we use data from existing editorial placements it also means that there is no extra work to manage. We have worked on optimising the placement on this and we are now getting over 3 million News Feed lazy loads being requested weekly and over 500,000 extra page views. Considering this area of the site used to be blank this is a tidy return on investment. The latest enhancement is to grey out stories you have read to give an even bigger prominence to stories you have yet to consume.</p>
<p><img src="/assets/images/metro-newsfeed-algorithm-works/timeline-alternative-styles-575x1024.png" alt="Current Timeline Styling (Trending, Normal, Read, Editorial)"></p>
<p><img src="/assets/images/metro-newsfeed-algorithm-works/Timeline-Title-Clicks-1024x725.png" alt="Clicks on Title in Timeline (Weekly)"></p>
<p><img src="/assets/images/metro-newsfeed-algorithm-works/Timeline-Image-Clicks-1024x637.png" alt="Clicks on Image within Timeline (weekly)"></p>
<p>The other large jumps in interactions were triggered by:</p>
<ul>
<li>Changing the height on when additional content was pulled in</li>
<li>Increasing the size of images for trending stories</li>
<li>Putting comments behind a tab and making timeline the default view</li>
</ul>
<p>The hardest part of this process was getting all the data in the right place from the APIs in the first place. Once this was present and we had a nice API around this the rest of this process was a iterative effort between editorial and development. There are a lot of moving parts but the benefits of having a site that reacts to users behaviours and works 24/7 is something that we feel is hugely worthwhile.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>10 growth hacks that helped Metro.co.uk achieve 27 Million Monthly visitors</title>
    <link href="https://blog.david-jensen.com/ten-growth-hacks-metro-27-million-monthly-unique-visitors/"/>
    <updated>2014-03-04T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/ten-growth-hacks-metro-27-million-monthly-unique-visitors/</id>
    <content type="html"><![CDATA[
      <p>Metro Monthly Unique Visitors (Jan'12 - Feb'14)</p>
<p>Over the past 12 months Metro has been on an amazing growth curve. Some of it is being in the right place at the right time for algorithm changes but a lot of it was planning and then execution of a growth (hacking) strategy.</p>
<h2>Hack 1: Responsive Design</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Metro-Monthly-Uniques-Mobile-1024x609.png" alt="Metro Mobile Monthly Unique Visitors"> Monthly Unique Visitors from Mobile (Jan'12 - Feb'14)</p>
<p>We decided a responsive design would be the best way to capitalise on the explosive growth in mobile. A nine month redesign process culminated in Metro going responsive on 7th Dec '12. We immediately saw growth from social referrals with Twitter's almost doubling over night. The other benefit of responsive sites is that there is only one URL. As this is the key used to store ranking information in search and social algorithms you don't want this split between multiple domains like m dot.</p>
<blockquote>
<p>The key takeaway is that if you give people a great experience on all devices then they are much more likely to read, share and return to your content.</p>
</blockquote>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/twitter-referral-visits-nov12-feb13-1024x576.png" alt="Twitter referral visits Nov '12 - Feb '13"> Weekly Visits from Twitter (Oct'12 - Feb'13)</p>
<h2>Hack 2: Focus all development efforts on growth</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Screen-Shot-2014-03-04-at-12.46.50-1024x469.png" alt="WordPress.com Stats for Metro"> WordPress.com Stats for Metro (Dec'12 - Feb'14)</p>
<p>We also migrated to the hosted platform as a service provided by Automattic on vip.wordpress.com. This enabled all of our costs and resources to be focused on growth as they didn't have to worry about caching, servers or anything that didn't improve experience for our readers or editorial users. The amazing thing about the platform is that it is a flat fee. This means that although our traffic has grown 350% year on year our costs have not changed. The depth of their out of the box features plus ecosystem of plugins ensured that we did't have to worry about commodity features such as SEO, site maps and editorial workflows as someone else had built and open sourced an approach.</p>
<h2>Hack 3: Open up content creation to anyone</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/metro-blogs-traffic-1024x654.png" alt="Metro Blogs Monthly Unique Users"> Metro Blogs Monthly Unique Users (Dec'12 - Feb'14)</p>
<p>The other great thing about the WordPress platform is that it enabled us to allow bloggers to contribute content directly into our core CMS. This started out as a feature for Metro employees but grew to encompass a much wider set of sources. Club Metro is now the most prominent and now contributes over 1M unique visitors a month. Having blogs content on the same domain placed amongst the rest of Metro's content ensured we leveraged our existing algorithmic rankings. A single editorial workflow also helped keep the overheads low. The added bonus that most bloggers were already using WordPress and can write from anywhere helped us secure some top talent.</p>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Screen-Shot-2014-03-04-at-13.08.38.png" alt="Club Metro Article"> Club Metro Article</p>
<h2>Hack 4: Facebook page as a major marketing channel</h2>
<blockquote>
<p>173,000 Facebook Page likes Feb '13 to 562,000 Facebook Page Likes Feb '14</p>
</blockquote>
<p>Social referrals were another large contributor to growth. We focused on growing our Facebook page &quot;Likes&quot; as a content marketing strategy and this was very successful. We had always been careful to only send a small amount of our best posts out a day on our Facebook page. This had a solid base of users and growing this was a key goal for the last year. We employed many strategies including competitions with like gates and boosting posts. Competitions were effective in bringing in users but there were a lot of repeat entries. Varying the prize helped to minimise this and our email based CRM platform really helped to drive entries. The most cost effective way we found was boosting posts as friends of people who already liked Metro were shown a great piece of our content. They were then much more likely to then go on to like the page. As they were similar to people who already liked Metro they were very receptive and continued to engage with our content.</p>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Screen-Shot-2014-03-04-at-12.52.27.png" alt="Metro Facebook Page"> Metro Facebook Page</p>
<h2>Hack 5: Made to share content</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/metro-social-referrals-1024x633.png" alt="Weekly Social Visits to Metro"> Weekly Social Visits to Metro (Jan'13 - Feb'14)</p>
<p>Ensuring that not just the content put out on the Facebook page was made to share also really helped grow our social referrals. When the content is written they set a success measure of 100 shares on an article and then set performance targets on achieving that on 25% of our content. This has allowed some interesting conversations around the areas of the site where that was less prevalent. More than anything it is a very easy test for all of the content creators to know what they should focus on. If it won't hit that bar then find something else. A key growth hack we developed was the ability to show different headlines for social and search so we didn't impact our search traffic.</p>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Metro-Social-Content.png" alt="SEO and Social Headlines on Made to Share Content"> SEO and Social Headlines on Made to Share Content</p>
<h2>Hack 6: Made to share UX</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/metro-made-to-share.png" alt="Share and follow functionality on Metro.co.uk after the Made to Share focus."> Share and follow functionality on Metro.co.uk after the Made to Share focus.</p>
<p>The other side of social was increasing the number of people sharing from the site. The development team had a made to share focus where we introduced much larger, clearer social buttons and reduced the number of clicks it took to share. This with the addition of a sticky sharing bar that floats on desktop has seen a large increase in the number of direct shares from our site. This seems to have also affected the amount of people copying and pasting links from the site from the subtle reinforcement due constantly present share cues. It would also seem that Facebook take direct site shares as a strong signal in their algorithm as we have continued to see growth from social.</p>
<h2>Hack 7: If something feels wrong don't give up on it</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/metro-search-referrals-1024x687.png" alt="Referral from Natural Search (Dec'12 - Feb'14)"> Referral from Natural Search (Google Fixed, July '12)</p>
<p>After the redesign only 20% of our stories indexed in Google News had our pictures next to them. We spent months experimenting on different options before we finally managed to ask Google the right question in July '13 so they could fix it for us. It turned out that they were still using the Webmaster Tools account we had been using before the migration which pointed to our old domain that included www. Not only did this change help our referrals from Google News but it gave us a major kick in all search referrals. It would have been much easier to give up on this earlier but relentlessly focusing on this until we solved it really paid dividends.</p>
<h2>Hack 8: Let technology automate repetition</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/metro-releases-1024x636.png" alt="Metro Development Releases to Production"> Metro Development Releases to Production (Nov'12 - Feb'14)</p>
<p>Automation of all of our development and test processes allowed us to release 4.5 times on average every day (apart from Fridays) for the past 12 months. This enabled short feedback cycles and decision making to happen at a much faster pace. We have five different environments that are used for testing before we push code live. This kept errors to a minimum and kept the feedback flowing. This environment of automated front end tests and frameworks was a major investment but has continued to pay dividends.</p>
<h2>Hack 9: Ensure proximity of key people who are focusing on a goal</h2>
<blockquote>
<p>Single Goal: 700,000 Average Daily Mobile Visitors in September 2013</p>
</blockquote>
<p>A single goal of growth allowed us to work together cross functionally and a focus on data and numbers ensured that feedback was alway digestible. Content, social and tech sitting together and working together enabled the good ideas to come to the top quicker and equally the bad ones get ignored. Equally focusing on data helped take emotion out of decision making which enabled data to win arguments. This sped up innovation and focus. In most cases we have done less but done what we have done better to achieve growth.</p>
<h2>Hack 10: Get out of the way</h2>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Screen-Shot-2014-03-04-at-12.22.49.png" alt="Voticle: Are you a true Brit?"> Voticle: Are you a true Brit?</p>
<p>Once people are working cross functionally together towards a goal then get out of the way and let them get on with it. In the past two months we have relaxed our process and now the content creators are working directly with the developers on new article formats to continue our growth. Out of this we have developed five new ways of displaying content from quizzes to lists and beyond.</p>
<p><img src="/assets/images/ten-growth-hacks-metro-27-million-monthly-unique-visitors/Screen-Shot-2014-03-04-at-12.23.06.png" alt="Quizicle: How much of a Londoner are you."> Quizicle: How much of a Londoner are you.</p>
<h2>Conclusion</h2>
<p>None of the above would have been possible without the adoption of a lean mindset and the approach of <a href="/build-measure-learn-iterate-vision-agile-future/" title="build, measure, learn, iterate">build, measure, learn, iterate</a>. It has been an amazing 12 months of growth at Metro and an great feeling to be part of a team that came up with and then executed a plan which delivered these results.</p>
<p>It was a pleasure to work with the below as well as many others on this journey.</p>
<ul>
<li>Martin Ashplant <a href="https://twitter.com/mashplant">@mashplant</a></li>
<li>Jack Dearlove <a href="https://twitter.com/jackdearlove">@jackdearlove</a></li>
<li>Richard Moynihan <a href="https://twitter.com/richjm">@richjm</a></li>
<li>Gareth Noon <a href="https://twitter.com/andfinally">@andfinally</a></li>
<li>Matteo Gildone <a href="https://twitter.com/domsmasher">@domsmasher</a></li>
<li>Matt Humphreys <a href="https://twitter.com/mhumph">@mhumph</a></li>
<li>Hoque Ali <a href="https://twitter.com/hoqueali">@hoqueali</a></li>
<li>Paul Kevan <a href="https://twitter.com/pkevan">@pkevan</a></li>
<li>Carlos Esteves <a href="https://twitter.com/kaley">@kalej</a></li>
<li>Dominic Rowell <a href="https://twitter.com/kaley">@domrowell</a></li>
<li>Jamie Walters <a href="https://twitter.com/kaley">@jamiewaltz</a></li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>SQL script for easy 301 redirect WordPress blog htaccess</title>
    <link href="https://blog.david-jensen.com/sql-script-301-redirect-wordpress-blog-htaccess/"/>
    <updated>2014-02-08T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/sql-script-301-redirect-wordpress-blog-htaccess/</id>
    <content type="html"><![CDATA[
      <p>I have just setup some 301 redirects in order to remove /development from the URL of my blog and wrote a handy piece of SQL to simplify 301 redirect WordPress blog htaccess. Once you have made the changes you can update your redirects /wp-admin/options-permalink.php. The reason I am redirecting to the guid which is the id based form is in case I change the slug in the future.</p>
<pre><code class="language-sql">SELECT CONCAT('Redirect 301 ','/slugtoreplace/', post_name, ' ', guid)
  FROM wpdb.wp_posts
 WHERE post_type = 'post'
   AND post_status = 'publish';
</code></pre>
<p>You can then post the output from that script into your .htaccess file and everything will redirect properly.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>SQL script to restore WordPress backup localhost</title>
    <link href="https://blog.david-jensen.com/sql-script-restore-wordpress-backup-localhost/"/>
    <updated>2014-02-01T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/sql-script-restore-wordpress-backup-localhost/</id>
    <content type="html"><![CDATA[
      <p>I needed a simple SQL script to help me restore WordPress backup localhost to ensure that I didn't have to go through the pain every time that I wanted to bring my data to my local server. This worked really well and all you need to do is search and replace on local.blog to the name of your localhost.</p>
<pre><code class="language-sql">-- update site
UPDATE wpdb.wp_site
   SET domain = 'local.blog'
 WHERE id = 1;

SELECT *
  FROM wpdb.wp_site;

-- update blog details
UPDATE wpdb.wp_blogs
   SET domain = 'local.blog'
 WHERE blog_id = 1;

SELECT *
  FROM wpdb.wp_blogs;

-- update site meta
UPDATE wpdb.wp_sitemeta
   SET meta_value = 'http://local.blog'
 WHERE meta_key = 'siteurl';

UPDATE wpdb.wp_sitemeta
   SET meta_value = '127.0.0.1'
 WHERE meta_key = 'dm_ipaddress';

SELECT *
  FROM wpdb.wp_sitemeta
 WHERE meta_key in ('siteurl','dm_ipaddress');

-- update options
UPDATE wpdb.wp_options
   SET option_value = 'http://local.blog'
 WHERE option_name in ('siteurl','home');

SELECT *
  FROM wpdb.wp_options
 WHERE option_name in ('siteurl','home');

-- update posts
UPDATE wpdb.wp_posts
   SET guid = REPLACE(guid,'blog.david-jensen.com','local.blog');
</code></pre>
<p>I have gone through each of the tables above that need updating, you could probably get away without updating all of these but I figure that as it is a script you might has well do it properly. I have also included the select statements afterwards to ensure that you can see the value has changed.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Communication and trust are the foundation of high performing teams</title>
    <link href="https://blog.david-jensen.com/communication-trust-foundation-high-performing-teams/"/>
    <updated>2014-01-27T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/communication-trust-foundation-high-performing-teams/</id>
    <content type="html"><![CDATA[
      <p>High performing teams can achieve unbelievable performance multipliers over sets of like minded individuals. I have spent the last few years working on building high performing teams and from this experience I have found the foundation of high performance is communication and trust.</p>
<h2>It takes time</h2>
<p>It is hard to get communication right within a team, even when they are sitting next to each other. Often it can take months rather than weeks to build up the right cadence of communication and understanding that are required to build trust. This process is even harder when you are also in the midst of creating a new company as it is only one of the many things that require focus. Luckily there are templates that help you hack these processes to make them happen quicker.</p>
<h2>Agile mindset</h2>
<p>Working with an agile mindset encourages regular feedback and can provide templates for the flow of information and cadence of communication. It also gives you the regular opportunity to tweak your process to ensure that it fits your environment in the form of retrospectives. Proximity is another clear hack and the closer that people sit the easiest it is to get them to communicate.</p>
<h2>Standups</h2>
<p>I have found that daily stand ups are a great way to hack communication within teams. I do daily stand ups with development teams and at least weekly stand ups with the business and stakeholders. These are best done around the agile wall and include new features as well as an overview of roadmaps. Regular feedback in the form of small regular conversations beats larger infrequent conversations as they allow for regular course correction. This helps prevent waste that comes from working on things that are not the most important for the business.</p>
<h2>Consistency of language</h2>
<p>The other benefit of regular communication is that both sides have the ability to learn the others language. Having a commonly understood language takes time and reduces the waste caused by miscommunication. Trust is much easier to lose than it is to build and in the majority of cases it is a miscommunication that leads to erosion of trust.</p>
<h2>Find common ground</h2>
<p>When people are under pressure to deliver it can be easy to blame something you don't understand. There are many different cultures that make up an organisation and how you build a software system isn't the same as how you create budgets. In order for cultures to understand each other you need to establish regular communication over common ground.</p>
<h2>Have a clear vision</h2>
<p>Common ground should be a clear vision based around a set of hard but achievable goals that everyone can affect. Clear goals enable decision making to be decentralised which helps to avoid one person blocking progress. Maintaining flow is essential to the creation of momentum which forms the baseline of high performance. Making your vision and current goals very visible should allow your team to see how the work that they are doing is affecting the key business metrics.</p>
<h2>Conclusion</h2>
<p>When teams are communicating well within a clear framework of success it allows everyone to focus on delivering value. The ability to influence business goals with regular feedback creates an ideal environment for high productivity. Communication is an often over looked discipline when forming teams and especially companies. It is the foundation of common understanding and this builds trust that will allow you take your performance from good to great.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How to install Varnish Cache on AWS Centos to speed up WordPress Apache</title>
    <link href="https://blog.david-jensen.com/install-varnish-cache-centos-speed-up-wordpress-apache/"/>
    <updated>2014-01-12T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/install-varnish-cache-centos-speed-up-wordpress-apache/</id>
    <content type="html"><![CDATA[
      <p>I have decided to give my server the final boost in my quest for ultimate cachability and install <a href="https://www.varnish-software.com/" title=" Varnish Cache">Varnish</a> cache. It was a toss up between doing this and installing NGINX but I have a reasonably large set of rules in my .htaccess to prevent hackers and 301s so I figured the migration would be a bit more than the few hours I had to spare.</p>
<p>First install varnish.</p>
<pre><code class="language-bash">sudo yum install varnish
</code></pre>
<p>Make sure that it comes back on startup.</p>
<pre><code class="language-bash">chkconfig varnish on
</code></pre>
<p>Now edit the following file.</p>
<pre><code class="language-bash">sudo vim /etc/sysconfig/varnish
</code></pre>
<p>The below is what I ended up with in my file thanks to <a href="https://icnerd.com/2013/08/12/dynamic-backend-servers-varnish/" title="Varnish Config">this</a>. The main difference from the original is the change of the VARNISH_STORAGE_TYPE to malloc which means that it is stored in memory rather than disk. I chose 128MB as my blog is pretty small and I wanted to have a bit of room to spare.</p>
<pre><code class="language-bash"># Varnish Users
VARNISH_RUN_USER=varnish
VARNISH_RUN_GROUP=varnish

# Should we start varnishd at boot?  Set to &quot;yes&quot; to enable.
START=yes

# Maximum number of open files (for ulimit -n)
# NFILES=131072

# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
MEMLOCK=82000

# Maximum number of threads (for ulimit -u)
NPROCS=&quot;unlimited&quot;

# Maximum size of corefile (for ulimit -c). Default in Fedora is 0
DAEMON_COREFILE_LIMIT=&quot;unlimited&quot;
RELOAD_VCL=1

# Should probably change this
VARNISH_VCL_CONF=/etc/varnish/default.vcl

# Not setting VARNISH_LISTEN_ADDRESS makes Varnish listen on all IPs on this box
# (Both IPv4 and IPv6 if available). Set manually to override this.
# VARNISH_LISTEN_ADDRESS=
VARNISH_LISTEN_PORT=80

# Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082

# Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret

# The minimum number of worker threads to start
VARNISH_MIN_THREADS=50

# The Maximum number of worker threads to start
VARNISH_MAX_THREADS=5000

# Idle timeout for worker threads
VARNISH_THREAD_TIMEOUT=120

# Best option is malloc if you can. malloc will make use of swap space smartly if
# you have it and need it.
VARNISH_STORAGE_TYPE=malloc

# Cache file size: in bytes, optionally using k / M / G / T suffix,
# or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=128M

VARNISH_STORAGE=&quot;${VARNISH_STORAGE_TYPE},${VARNISH_STORAGE_SIZE}&quot;

# Default TTL used when the backend does not specify one
VARNISH_TTL=60

# DAEMON_OPTS is used by the init script.  If you add or remove options, make
# sure you update this section, too.
DAEMON_OPTS=&quot;-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -t ${VARNISH_TTL} \
             -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
             -u ${VARNISH_RUN_USER} -g ${VARNISH_RUN_GROUP} \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}&quot;
</code></pre>
<p>Then you need to edit your /etc/varnish/default.vcl the below is what I ended up with which allows you to see the WordPress Admin Bar but caches most other bits. It also takes invalidation requests from the Varnish WordPress Plugin which is the easiest way to keep your content fresh.</p>
<pre><code class="language-vcl">backend default {
  .host = &quot;127.0.0.1&quot;;
  .port = &quot;8080&quot;;
}

acl purge {
  &quot;localhost&quot;;
}

sub vcl_recv {
  if (req.request == &quot;BAN&quot;) {
    if(!client.ip ~ purge) {
      error 405 &quot;Not allowed.&quot;;
    }
    ban(&quot;req.url ~ &quot;+req.url+&quot; &amp;&amp; req.http.host == &quot;+req.http.host);
    error 200 &quot;Banned.&quot;;
  }

  if (req.request != &quot;GET&quot; &amp;&amp;
      req.request != &quot;HEAD&quot; &amp;&amp;
      req.request != &quot;PUT&quot; &amp;&amp;
      req.request != &quot;POST&quot; &amp;&amp;
      req.request != &quot;TRACE&quot; &amp;&amp;
      req.request != &quot;OPTIONS&quot; &amp;&amp;
      req.request != &quot;DELETE&quot;) {
    return (pipe);
  }

  if (req.request != &quot;GET&quot; &amp;&amp; req.request != &quot;HEAD&quot;) {
    return (pass);
  }

  # don't cache authenticated sessions
  if (req.http.Cookie &amp;&amp; req.http.Cookie ~ &quot;(wordpress_|PHPSESSID)&quot;) {
      return(pass);
  }

  # don't cache ajax requests
  if(req.http.X-Requested-With == &quot;XMLHttpRequest&quot; || req.url ~ &quot;nocache&quot; || req.url ~ &quot;(control.php|wp-comments-post.php|wp-login.php|bb-login.php|bb-reset-password.php|register.php)&quot;) {
      return (pass);
   }

  if (req.url ~ &quot;wp-(login|admin)&quot; || req.url ~ &quot;preview=true&quot;) {
    return (pass);
  }

  remove req.http.cookie;
  return (lookup);
}

sub vcl_fetch {
  if (beresp.status =&gt; 400) {
    set beresp.ttl = 0m;
    return(hit_for_pass);
  }

  if (req.url ~ &quot;wp-(login|admin)&quot; || req.url ~ &quot;preview=true&quot;) {
    return (hit_for_pass);
  }

  set beresp.ttl = 24h;
  return (deliver);
}
</code></pre>
<p>You then need to update your Apache to listen to port 8080 as Varnish will be listening on port 80.</p>
<pre><code class="language-bash">sudo vim /etc/httpd/conf/httpd.conf
</code></pre>
<p>Update Listen 80 to Listen 8080 and then restart Apache and Varnish and then you can run varnishstat to see the details of how your cache is performing.</p>
<pre><code class="language-bash">sudo service httpd restart
sudo service varnish restart
varnishstat
</code></pre>
<p>I then installed the <a href="http://wordpress.org/plugins/wordpress-varnish/faq/" title="Varnish WordPress Plugin">Varnish WordPress Plugin</a> and then went to Dashboard -&gt; Settings -&gt; WP-Varnish and updated the following fields.</p>
<ul>
<li>Varnish Administration IP Address</li>
<li>Varnish Administration Port</li>
<li>Varnish Administration Secret</li>
</ul>
<p>The secret is a GUID which is stored in the below.</p>
<pre><code class="language-bash">sudo vim /etc/varnish/secret
</code></pre>
<p>These are some really useful Varnish commands to see how your cache is performing or check out the <a href="https://www.varnish-cache.org/docs/3.0/index.html" title="Varnish Docs">docs</a> for full details.</p>
<ul>
<li>varnishtop: like top but for varnish.</li>
<li>varnishhist: histogram of request time</li>
<li>varnishstat: cache hits, resource consumption and many other data points</li>
<li>varnishlog: log of all requests made to the cache</li>
</ul>
<p>You should then have a super charged server where most of the files are coming from memory rather than disk. The below sites were helpful along this journey.</p>
<p><a href="https://scalr-wiki.atlassian.net/wiki/display/docs/Install+Varnish+HTTP+Accelerator+with+WordPress">Install Varnish HTTP Accelerator with WordPress</a> <a href="http://ocaoimh.ie/2011/08/09/speed-up-wordpress-with-apache-and-varnish/">Speed up WordPress with Apache and Varnish</a> <a href="http://mclear.co.uk/2011/10/05/wordpress-varnish-cache-config-vcl/">WordPress Varnish Cache Config / VCL</a></p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Making change a habit is the best way to create an agile mindset</title>
    <link href="https://blog.david-jensen.com/change-a-habit-create-agile-mindset/"/>
    <updated>2014-01-04T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/change-a-habit-create-agile-mindset/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/change-a-habit-create-agile-mindset/gandhi.jpg"></a> <a href="http://www.flickr.com/photos/reidab/6331101382/in/photolist-aDsxSo-878Nwe-bamY7P-8i7V9x-99LsEa-84cKNc-8F8cpa-cm9oz5-dBTDPq-cm9pmm-cnJDKS-adePWk-9qApbG-8rkgC5-advwoo-et731u/">Photo</a> by <a href="http://www.flickr.com/photos/reidab/">Reidab</a> | <a href="http://creativecommons.org/licenses/by/2.0/">CC BY</a></p>
<blockquote>
<p>“You must be the change you wish to see in the world.” Mahatma Gandhi</p>
</blockquote>
<p>Making change a habit is a powerful way of not just creating but maintaining an agile mindset. In the fast paced world that we occupy an agile mindset has come to be valued over many other attributes of successful companies. Agile is a word that is often used without a true understanding of the mindset that underpins its values.</p>
<h2>Mindsets</h2>
<p>A <a href="http://en.wikipedia.org/wiki/Mindset" title="Mindset">mindset</a> is &quot;a set of assumptions, methods, or notations held by one or more people or groups of people that is so established that it creates a powerful incentive within these people or groups to continue to adopt or accept prior behaviors, choices, or tools&quot;. Another way of looking at that is a set of habits which an individual/group perform similar outcomes to. Agile has its origins in software development with the Agile Manifesto which was signed in 2001 and outlines the mindset needed to create successful software. The group that signed the <a href="http://agilemanifesto.org" title="Agile Manifesto">Agile Manifesto</a> stated that they value:</p>
<ul>
<li>Individuals and interactions over processes and tools</li>
<li>Working software over comprehensive documentation</li>
<li>Customer collaboration over contract negotiation</li>
<li>Responding to change over following a plan</li>
</ul>
<h2>How your brain works</h2>
<p>In order to better understand how you create the set of habits that form a mindset it helps to understand how the brain works. There are two distinct systems in your brain used for thinking as described by Daniel Kahneman in his book &quot;<a href="http://en.wikipedia.org/wiki/Thinking,_Fast_and_Slow" title="Thinking Fast and Slow">Thinking Fast, Thinking Slow</a>&quot;.</p>
<ul>
<li>System 1: Fast, automatic, frequent, emotional, stereotypic, subconscious</li>
<li>System 2: Slow, effortful, infrequent, logical, calculating, conscious</li>
</ul>
<p>System 1 is where you spend most of your time and could be described as the autopilot part of your brain. Basically this allows you to do complex things without large amounts of energy and effort. System 2 is what you use when you encounter a problem that System 1 doesn't recognise and this requires a different deeper type of thought.</p>
<p>Most people spend the majority of their time using the System 1 part of their brain. However like most things System 2 becomes more effective the more you utilise it. If you can take something from System 2 and engrain it in System 1 then you are then able to spend the energy you save on solving new problems. It also becomes the default behaviour for how you respond to this type of situation.</p>
<h2>Habits</h2>
<p>Another way to describe this type behaviour is a habit, defined as &quot;A settled or regular tendency or practice, esp. one that is hard to give up&quot; or simply something which has been engrained in System 1. They can be created and/or modified and a great description of this process can be found in &quot;<a href="http://charlesduhigg.com/the-power-of-habit/" title="The Power of Habit">The Power of Habit</a>&quot; a book by Charles Duhig. He defines a habit of consisting of the following:</p>
<ul>
<li>A trigger</li>
<li>A routine (what you do to respond to the trigger)</li>
<li>A reward</li>
</ul>
<p>The easiest way to change a habit is to understand what the trigger and reward are and to replace the routine in the middle with a newer improved version. There are many triggers that exist in the software development lifecycle such as being stuck on a problem or lack of detail in requirements definition. When you start out most people have different routines for dealing with these type of problems. The ideal place to start to discuss these triggers is in a retrospective. In this environment it is great to understand the differing approaches and choose the most effective one for the group to adopt. The reward for this is the great feeling of shipping quality code on a regular basis.</p>
<h2>Change a habit</h2>
<p>I have found that to change a habit it is always best to start small and find a habit that will be reasonably straightforward to improve. This allows people to understand the process and see the benefits of the approach. I have also found that small regular conversations are much more effective for changing habits than large infrequent conversations. It takes a while for the habit to form and change and being subtly reminded on a regular basis is great way to reinforce the correct behaviour.</p>
<p>In order to create a mindset for a team you need to gradually change their individual habits to be consistent. This is not an easy or quick task but one that delivers an amazing amount of long term benefit to both the individuals and the company/team that they work for. This is probably the single largest factor in turning people into high performing teams due to the efficiency gains and consistency of outputs. If they have made a habit of hacking habits then they are constantly improving and helping each other to do the same.</p>
<h2>Conclusion</h2>
<p>It has taken me a few years to create a habit of change at Metro and these are some of the practical things that I did to help that journey. Initially I set a very clear high level goal of releasing software every day. This required a lot of changes and I wanted to ensure people knew what success looked like. I then setup regular retrospectives to create a change dialog. I then gave everyone my word that I would be a willing participant of this journey into change and set a clear commitment to remove impediments. This mainly involved getting the business and stakeholders to change alongside our journey. Once this was setup we started small, started changing and are iterating as there is no such thing as perfect process.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How to speed up WordPress Apache using Batcache Multisite and Memcache on CentOS</title>
    <link href="https://blog.david-jensen.com/speed-wordpress-using-batcache-multisite-memcache/"/>
    <updated>2013-12-26T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/speed-wordpress-using-batcache-multisite-memcache/</id>
    <content type="html"><![CDATA[
      <p>I run a small WordPress network on an Amazon Micro Instance and this means that I need to stay on top of caching. Having had a look around at a lot of different options I decided that I would use Batcache and Memcache to provide me with in memory caching should one of my posts get popular. Batcache multisite capabilities means that I don't have to stress about individual caching setups per site. Also Batcache is what WordPress.com uses to handle caching and you can utilise Memcache in a distributed way should you need to scale out from a single server.</p>
<p>Another reason I like it is that it is very non-invasive caching technique, I know that WP-Super-Cache and the way that it generates static files is probably a better fit for my blog as the load isn't usually very concurrent. However that sounded quite straight forward and I like a command line challenge plus I have a few side projects that this might come in handy for. You also need to get this setup if you are ever deploying anything to WordPress.com which we utilise for our hosting at <a href="http://metro.co.uk" title="Metro.co.uk">Metro.co.uk</a>.</p>
<p>As I am running a network, I don't want other users to have to worry about caching and its quirks. The nice thing about Batcache is that it doesn't cache anything when you have cookies from the domain so anyone who is writing can see their changes immediately. I think this and its simplicity is probably the key advantage over some other methods of caching.</p>
<p>The other thing is that if you have root access to your server then it is reasonably straight forward and I thought that I would share how I did this here in case anyone else is interested.</p>
<p>First install all of the libraries that you need to run memcache and access it via PHP, it took me a few times to get this right so there might be a few libraries which are extra below.</p>
<pre><code class="language-bash">sudo yum install memcached
sudo yum install php-pecl-memcache
sudo yum install zlib-devel
sudo yum install php-pear
sudo yum install php-devel
sudo yum install libmemcached-devel
</code></pre>
<p>This is the compiler I used for building</p>
<pre><code class="language-bash">sudo yum install gcc
</code></pre>
<p>This will build the libraries that PHP needs to be able to access Memcache</p>
<pre><code class="language-bash">sudo pecl install memcached
</code></pre>
<p>Now make sure that memcached will start on startup</p>
<pre><code class="language-bash">sudo chkconfig memcached on
</code></pre>
<p>I also enabled memcache session handling but haven't turned it on.</p>
<pre><code>Enable memcache session handler support? [yes] : yes
</code></pre>
<p>I didn't do as it suggested below as every time I did I got errors saying that it had already been registered.</p>
<pre><code>You should add &quot;extension=memcached.so&quot; to php.ini
</code></pre>
<p>I had a look at the config and tried to lock it down to localhost only but it kept on throwing errors when I did so I left it, as all of my ports are locked down via the Amazon Firewall this shouldn't be an issue.</p>
<pre><code class="language-bash">sudo vim /etc/sysconfig/memcached
</code></pre>
<p>Now made sure that it would come back on startup.</p>
<pre><code class="language-bash">sudo chkconfig memcached on
</code></pre>
<p>Now I followed these <a href="http://wordpress.org/plugins/batcache/installation/" title="Batcache Installation">instructions</a> for Batcache installation once I had downloaded it.</p>
<p>Upload advanced-cache.php to the /wp-content/ directory</p>
<p>Add this line the top of wp-config.php to activate Batcache:</p>
<pre><code class="language-php">define('WP_CACHE', true);
</code></pre>
<p>Tweak the options near the top of advanced-cache.php, I set mine to cache for 60 minutes after being hit twice in 10 minutes.</p>
<pre><code class="language-php">var $max_age =  3600; // Expire batcache items aged this many seconds (zero to disable batcache)
var $seconds =    600; // ...in this many seconds (zero to ignore this and use batcache immediately)
</code></pre>
<p>Optional Upload batcache.php to the /wp-content/plugins/ directory. As I ran Multisite I put this in the /wp-content/mu-plugins so it would be there for all of the sites in my network.</p>
<p>We have already installed the PECL memcached extension so you just need to add <a href="http://svn.wp-plugins.org/memcached/trunk/" title="Batcache Memcached Trunk">Ryan's Memcached backend 2.0</a> to wp-content.</p>
<p>Test by reloading a page in your browser several times and then viewing the source once you have cleared any cookies from the domain you are hitting. Just above the closing tag in the head you should see some Batcache stats.</p>
<pre><code>generated 524 seconds ago
generated in 0.374 seconds
served from batcache in 0.002 seconds
expires in 3076 seconds
</code></pre>
<p>Now feel free to tweak the settings around cache time to a period where you will reduce the load. Remember this is full page caching and you shouldn't see it if you are logged in.</p>
<h2>SEO Impact</h2>
<p>The best part of installing Batcache has been the impact on SEO, below are my crawl stats from Google and you can see that the average time spent downloading a page flatlines around the beginning of December after installing Batcache. The really interesting thing is that the pages crawled per day went up at the same time. I think this is because Google now thinks that that server can handle a much greater load so sends it its bots on a more regular basis. Can't say that this has had a massive impact on my SEO entries but it is a really good sign of the impact that you can have with a proper caching strategy.</p>
<p><a href="/assets/images/speed-wordpress-using-batcache-multisite-memcache/google-crawl-stats.png"><img src="/assets/images/speed-wordpress-using-batcache-multisite-memcache/google-crawl-stats.png" alt="Google Crawl Stats"></a></p>
<p>Super fast and simple caching, if its good enough for WordPress.com its good enough for me. The below articles helped me along this journey.</p>
<ul>
<li><a href="https://www.digitalocean.com/community/articles/how-to-install-and-use-memcache-on-ubuntu-12-04" title="How to install Memcache">How To Install and Use Memcache on Ubuntu 12.04</a></li>
<li><a href="http://evansolomon.me/notes/faster-wordpress-multisite-nginx-batcache/" title="Faster WordPress Multisite Nginx Batcache">Faster WordPress: Multisite, nginx, and Batcache</a></li>
<li><a href="http://andy.wordpress.com/2008/06/22/batcache-for-wordpress/" title="Batcache for WordPress">Batcache for WordPress</a></li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>Wendy Lea from Get Satisfaction on Customer Driven Development</title>
    <link href="https://blog.david-jensen.com/wendy-lea-get-satisfaction-customer-driven-development/"/>
    <updated>2013-11-03T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/wendy-lea-get-satisfaction-customer-driven-development/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/wendy-lea-get-satisfaction-customer-driven-development/get-satisfaction.jpg"></a></p>
<p><a href="https://twitter.com/WendySLea" title="Wendy Lea">Wendy Lea</a> the CEO of <a href="https://getsatisfaction.com/corp/" title="Get Satisfaction">Get Satisfaction</a> gave a presentation at the DMGT Technology Summer School on &quot;The voice of the customer&quot;. There were some great points on how they have infused passion for their customers into a customer driven development process. As their business is based completely on capturing customer feedback it was great to see how they have infused their company mission throughout everything that they do. I have collated the main points I took from the talk below.</p>
<ul>
<li>&quot;Listen -&gt; Engage -&gt; Iterate&quot; is their mantra for development</li>
<li>&quot;Advocate -&gt; Discover -&gt;  Buy&quot; is a common loop for new customers</li>
<li>You need to create and curate a community for product development (Facebook, Twitter handle)</li>
<li><a href="http://www.cluetrain.com/book/index.html" title="The Cluetrain Manifesto">The Cluetrain Manifesto</a> - &quot;The connectedness of the Web is transforming what's inside <em>and</em> outside your business — your market and your employees.&quot;</li>
<li>Create systems of engagement mashing in your external and external systems</li>
<li>Conversations created by real people, in their natural language are very powerful and discoverable</li>
<li>Bidirectional conversation can help that flow</li>
<li>Join the conversation:
<ul>
<li>Embrace customer conversation</li>
<li>Open these conversations</li>
<li>Collaborate</li>
<li>Apply actionable insights</li>
</ul>
</li>
</ul>
<p>Embracing the above thoughts into a customer driven development process is something that really got me thinking on how we might be able to apply this at Metro. Apart from the old letters page newspapers traditionally are more of a one way dialogue. I have been thinking of ways that we could apply some of the above and simple feedback forms are something we are going to begin trialling soon as we make further changes to Metro.co.uk.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Strategic Perspectives from Bill Raduchel</title>
    <link href="https://blog.david-jensen.com/strategic-perspectives-bill-raduchel/"/>
    <updated>2013-11-03T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/strategic-perspectives-bill-raduchel/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/strategic-perspectives-bill-raduchel/technology-summer-school.jpg"></a></p>
<p>I had the pleasure of spending some time at the DMGT Technology Summer School with <a href="http://www.linkedin.com/in/wjraduchel" title="Bill Raduchel">Bill Raduchel</a>. He had a long and interesting career before joining DMGT as a technology advisor to the board. I managed to capture some of his advice below and a couple of quotes which resonated well with me.</p>
<blockquote>
<p>&quot;Heroism is an act of stupidity that you happen to survive.&quot; Bill Raduchel</p>
</blockquote>
<ul>
<li>Open source is the only way to get the best developers as they can learn portable skills</li>
<li>Proprietary systems are struggling</li>
<li>John Chambers CEO Cisco: We compete against market transitions not companies</li>
<li>You must get people loosely coupled but tightly aligned</li>
<li>You must have a vision and be able to sell it, you must communicate it in a way that all your employees can understand</li>
<li>Asking the right questions is never interference</li>
<li>You must set the boundaries and then get out of the way</li>
<li>Architecture is to empower your team, not constrain it</li>
<li>Commitment before success is the mentality that separates people in a startup from people in a corporation</li>
</ul>
<blockquote>
<p>&quot;Mindset is a value that has become a habit.&quot; - Bill Raduchel</p>
</blockquote>

    ]]></content>
  </entry>
  
  <entry>
    <title>Heidi Rozen: It&#39;s the business model, stupid</title>
    <link href="https://blog.david-jensen.com/heidi-rozen-business-model-stupid/"/>
    <updated>2013-11-03T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/heidi-rozen-business-model-stupid/</id>
    <content type="html"><![CDATA[
      <p>Heidi Rozen gave a great talk at the DMGT Technology Summer School simply titled &quot;Failure&quot;. A Silicon Valley Alumni she has started companies, worked for Apple under Steve Jobs and now is involved in Venture Capital so she had her fair share of stories. I was really impressed with her perspective on development and seemed to have a very Lean outlook after all of her experiences. I collated the points of her talk below and most of it resonated very well with how I am currently thinking.</p>
<ul>
<li>It's the business model, stupid - first place to start when a company isn't working</li>
<li>Most technical decisions are actually business decision</li>
<li>It's not just about money, it's also opportunity cost</li>
<li>Support the lunatic fringe</li>
<li>Understand the assumptions so you can quickly adjust when things don't work out and they don't</li>
<li>Innovate around what is core for you and outsource the rest</li>
<li>You are building for the platform of tomorrow, not of today</li>
<li>You must understand your customers ecosystem and fit in effortlessly</li>
<li>If you can't win then recognise early and deal with it</li>
<li>Think backwards from your customers</li>
<li>Narrow the customer set to provide 100% solution</li>
<li>Understand the ecosystem and the business model</li>
<li>Build 95% solution and pay 5% is Google solution</li>
<li>60% of VC's don't return on their capital</li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>How Metro built a metrics driven product development process</title>
    <link href="https://blog.david-jensen.com/metrics-driven-product-development/"/>
    <updated>2013-09-29T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/metrics-driven-product-development/</id>
    <content type="html"><![CDATA[
      <p>I have spent the last three years at Metro constantly tweaking our development process to fit our environment and teams maturity. At the same time the product development process had remained reasonably unchanged. Someone comes up with an idea we all have a debate about how good/bad we think it will be and someones opinion wins out the day. However in the last nine months we have also begun to iterate on this part of our process to make it more of a metrics driven product development process. It has been a slower process than I had anticipated and thought I would share some of the learning around that here.</p>
<p>I think that the lack of established templates to follow such as SCRUM has made this a harder process as there isn't a template to start from. I also think that in order to get it right the metrics need to be driven from the business, so you are dependent on them being engaged. The toolset that helps you move to this type of approach is also lacking and in the end we had to build/hack our own.</p>
<p>Our journey began by the business setting one key goal backed by a clear metric that the whole business could understand. This was easier said than done and were definitely parts of the business that feel left out by this singular approach. However just having one key metric in the beginning is very important as it aids focus. Metro's was to have an average of 700,000 daily mobile visitors in September 2013.</p>
<p>The next phase was to have a look at all the data that makes up the key metric and to break it down further to show each area of the business what they could effect. Being as open and honest about where the numbers have come from at this stage is essential. There will definitely be questions about how the decision was made especially if it is a large goal and being open at this stage is the best way to combat that (even if it it is a vanity/stretch target).</p>
<p>As the largest part of the goal was going to come from metro.co.uk and that partly my teams responsibility we started by looking at our web analytics (Omniture) to see what data we were already collecting. We also looked to the content and search teams to see what metrics they were tracking as only by working together would we be successful. Common goals should bring people together to talk about frustrations/improvements, this alignment should provide major benefits. However it still surprises me in large businesses how little people actually talk.</p>
<p>I think part of this problem is the fact that so many parts of the business have their own language. Development as much as anyone contributes to this as it takes quite a lot of time to be able to converse with most developers. Marketing, Sales and Content all also have their own ways of working and language which can be just as daunting for developers. Getting the translation right between these different groups so they can talk enough of the same language to communicate effectively is a major business benefit. I think this is one of the reasons that startups are able to iterate faster as they have to talk the same language as you have a limited set of people doing a lot of of different things but all speaking the same language.</p>
<p>Having had and looked at all the existing metrics we decided that there wasn't actually enough specific product based feedback mechanisms to measure the success of our work. So to understand the product more we had to build our own measurement/tracking framework on top of Omniture. This took some work to get right and then took even longer to get the tracking across our entire site. However once we were able to see the results of each of our improvements in both click perspective and overall impact on the wider numbers a really important feedback mechanism was created.</p>
<p>Measuring the impact was only the first part however we needed to get the data into a format that everyone could see and understand. This was to be a common theme throughout this process you go from having no data to having too much data that doesn't make a whole lot of sense. Having dedicated resources and time to create dashboards that compiled this data into meaning was the next step on this journey. Then we created regular meetings that talked around this data and tried to put meaning around it. Product Performance was born and we scheduled it in for every two weeks. We get all of the product owners and stakeholders that are involved in product development into a room and talk through performance of the previous two weeks. We also do a product based standup twice a week where all stakeholders stand in front of the Kanban board and discuss what is being done and about to drop into the process. Lots of small regular conversations definitely provide more value and leverage for change than large infrequent meetings.</p>
<p>We also got large televisions that monitored real time traffic and put them up in visible locations so everyone could see what was going on and feel the excitement when a large story took off. Real time data is the next step in this process and the faster you can see the data the faster you can react to it. The next step after having everything measured was to begin A/B testing. This step again proved to be a much harder than we initially thought. As our site is news based and constantly changing we found we couldn't really use a Javascript based framework like Optimisely as things changes too much. Plus the cost was very prohibitive for a site of our size. So we ended up building a simple framework that extended our measurement in Omniture.</p>
<p>The other key learning was as we release multiple changes everyday what do you test and what do you just measure. We got to a place that if you were working on an incremental improvement then A/B test otherwise just ensure that everything is measured. We were surprised as well that sometimes the A/B results were 50:50 but when we made then change anyway it had a longer term affect on user behaviour that was positive and not captured during the testing.</p>
<p>We also had some issues with our Google News Sitemap and indexation. This was out most experimented feature over months. We ended up creating a dedicated swim lane on our Kansan board just for this. We only ran one test at a time and then iterated to the next one. I think for harder more complex options running just one test at a time really helped focus in the results of each before moving on.</p>
<p>Running too many tests at the same time proved to be confusing and I ended up making one of the team the chief growth hacker and he became the go to person for what and how to run tests. Now that we are in a place with a nice testing framework and approach it was time to see if it would work towards a more major site redesign. We needed to break this big design down into testable chunks that would prove our hypothesis that people would interact more by scrolling than swiping. Creating stories that were just for learning felt like a natural evolution from a lean mindset.</p>
<h2>Conclusion</h2>
<p>It has been a really interesting nine months and we have managed to hit a goal that seemed completely unachievable only 12 months ago. I think we managed to create a measurement mindset where everyone asks what we are measuring before starting development. This added to the power of everyone pointing in the same direction, having a process that allows constant improvement and promotes communication has produced some amazing results. You should give it a go.</p>
<ul>
<li>Start with one key metric</li>
<li>Break metric down to provide relevance</li>
<li>Measure everything</li>
<li>Create dashboards to distill data</li>
<li>Make the data visible to everyone</li>
<li>Regular meetings (short and often) to create common language</li>
<li>Try running some A/B tests</li>
<li>Keep changes small and regular</li>
<li>Communicate, communicate, communicate</li>
<li>Enjoy your successes</li>
</ul>
<h2>Further Reading</h2>
<p>This blog post was picked up by The Media Briefing who further interviewed myself and Jamie Walters for a slightly different angle on the above. The post <a href="http://www.themediabriefing.com/article/how-the-metro-has-put-metrics-at-the-heart-of-product-development" title="How the Metro uses metrics to create flexible and effective digital products">How the Metro uses metrics to create flexible and effective digital products</a> is well worth a read.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How to setup an AWS EC2 instance to reduce WordPress hacker attacks</title>
    <link href="https://blog.david-jensen.com/ec2-centos-reduce-wordpress-hacker-attacks/"/>
    <updated>2013-09-16T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/ec2-centos-reduce-wordpress-hacker-attacks/</id>
    <content type="html"><![CDATA[
      <p>WordPress hacker attacks have been on the rise this year and although I haven't been hacked (touch wood) they have managed to overload my site on a number of occasions. I have been on a quest to stop them getting in and also to reduce the instances of their repeated entry attempts taking it down. This has been a pretty long journey and one that I thought other people might benefit from so I have decided to share it here.</p>
<h2>Monitoring</h2>
<p>The first step that I took was setting up alerts in the Amazon EC2 console to send me an email if my CPU stays at 100% for over five minutes. You can do this by clicking on your server in the console and then hitting the &quot;Monitoring&quot; tab and then &quot;Create Alarm&quot;. This seemed to be about the right amount of time to stop too many false positives and usually indicated that something was up with the server.</p>
<p>The second set of monitoring I setup was <a href="http://newrelic.com/" title="New Relic">New Relic</a>, we use them extensively at work to monitor our servers and their free version gives you a load of really useful information about how both the server and PHP are performing. Think of it as a version of Google Real Time that allows you to look at the processes and speed of everything going on inside your server and application. They also have a really useful availability monitoring service built in which you can setup to ping your site every few minutes to see if it is accessible and a great iPhone App that sends push notifications when something goes down.</p>
<ul>
<li><a href="https://newrelic.com/docs/server/server-monitor-installation-redhat-and-centos" title="Install New Relic Centos">Server monitor installation: RedHat and CentOS</a></li>
<li><a href="https://newrelic.com/docs/php/php-agent-installation-redhat-and-centos" title="Install New Relic PHP Agent Centos">PHP agent installation: RedHat and CentOS</a></li>
</ul>
<h2>Logs</h2>
<p>The next thing you need to do is SSH into your server and check your httpd access_log to see what is trying to access your server.</p>
<pre><code class="language-bash">sudo tail -f /etc/httpd/logs/access_log
</code></pre>
<p>This will bring up what is currently happening on your server and you can see all of the requests that are coming in. If your site does go down this is the place to check right afterwards to see what the requests were that overloaded it.</p>
<h2>Mod Security</h2>
<p>I decided to install <a href="http://www.modsecurity.org" title="Mod Security">Mod Security</a> along with the <a href="https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project" title="OWASP Mod Security">OWASP</a> ruleset to give myself an added extra layer of protection from any issues that might get introduced into WordPress before a patch comes out. I have to say that this involved quite a steep learning curve and due to the amount of technical information that I write in my blog so it took me a long time to modify all of the rules to allow saving of posts amongst other things.</p>
<p>As I am running on the AWS Centos image and it already had the <a href="http://www.thegeekstuff.com/2012/06/enable-epel-repository/" title="Enable EPEL Centos">EPEL</a> repository setup so all I needed to do was:</p>
<pre><code class="language-bash">sudo yum install mod_security mod_security_crs
sudo service httpd restart
</code></pre>
<p>Once this has installed you should definitely start clicking around your blog and see what is broken, quite likely that actions like saving a post, updating a comments status and updating plugins will now throw 403 errors. In order to allow your site to function need to create a file called whitelist.conf in the following location.</p>
<pre><code>/etc/httpd/modsecurity.d/activated_rules
</code></pre>
<p>You then need to populate it with rules that allow you to bypass the specific rules that are triggered when using WordPress. Mod_security isn't aware of your logged in status and assumes every call is external so this throws up quite a few issues. I have included a link to the ruleset that I have built up over the last few months below. There are probably more entries than most people will need but due to the geeky and code based nature of my posts a lot of stuff gets blocked, I have also enabled XMLRPC so apps work as well.</p>
<p><a href="/assets/images/ec2-centos-reduce-wordpress-hacker-attacks/whitelist.txt" title="whitelist.conf">whitelist.conf</a></p>
<h2>Adding your own rules to whitelist.conf</h2>
<p>Should you get a 403 error when performing any action on your site you should SSH to your server and via the terminal type in the below.</p>
<pre><code class="language-bash">sudo tail -f /etc/httpd/logs/modsec_audit.log
</code></pre>
<p>Then when you retry the action you should see another entry in the log and you need to pick out the data that looks like this.</p>
<pre><code>[id &quot;960035&quot;]
</code></pre>
<p>You then just need to add the following line to your whitelist.conf</p>
<pre><code class="language-apache">SecRuleRemoveById 960035
</code></pre>
<p>Under the correct Location e.g.</p>
<pre><code class="language-apache">&lt;LocationMatch &quot;/xmlrpc.php&quot;&gt;
  SecRuleRemoveById 981173
&lt;/LocationMatch&gt;
</code></pre>
<p>This can be quite a laborious process and possibly the whole lot is overkill but have to say I have learnt quite a bit in the process. I also added the following to the bottom of my http.conf which bans an IP from attempting to login for five minutes after three failed attempts.</p>
<pre><code class="language-apache"># Stop Brute Force Attack by banning IP
# http://www.frameloss.org/2011/07/29/stopping-brute-force-logins-against-wordpress/

# This has to be global, cannot exist within a directory or location clause
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:2323

# Setup brute force detection.

# React if block flag has been set.
SecRule user:bf_block &quot;@gt 0&quot; &quot;deny,status:401,log,msg:'ip address blocked for 5 minutes, more than 3 login attempts in 3 minutes.',id:2323&quot;

# Setup Tracking. On a successful login, a 302 redirect is performed, a 200 indicates login failed.
SecRule RESPONSE_STATUS &quot;^302&quot; &quot;phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:2324&quot;
SecRule RESPONSE_STATUS &quot;^200&quot; &quot;phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:2325&quot;
SecRule ip:bf_counter &quot;@gt 3&quot; &quot;t:none,setvar:user.bf_block=1,expirevar:user.bf_block=300,setvar:ip.bf_counter=0&quot;
</code></pre>
<h2>htaccess</h2>
<p>The final part of this is the .htaccess changes that I made to stop people being able to post without a referrer as a lot of bots use this method as they are computer programs rather than real people. I also had two specific User Agents that had targeted me which I block all access to my wp-login page.</p>
<pre><code class="language-apache"># Stop protected folders from being narked. Also helps with spammers
ErrorDocument 401 /401.html

# Stop spam attack logins and comments
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php*
RewriteCond %{HTTP_REFERER} !.*(blog.david-jensen.com|dev.mariamjensen.com|www.cafeontherye.co.uk).* [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/5\.0\ \(Windows\ NT\ 6\.1;\ WOW64\;\ rv\:18\.0\)\ Gecko/20100101\ Firefox/18\.0 [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/5\.0\ \(Parsley\ NT\ 1.0\;\ rv\:1.0\)\ Parsley/1.0.0.0 [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule .* - [F]
&lt;/ifModule&gt;
</code></pre>
<p>Here are a few sites that helped the creation of this post.</p>
<ul>
<li><a href="http://www.frameloss.org/2011/07/29/stopping-brute-force-logins-against-wordpress/" title="Stopping Brute-force Logins Against WordPress">Stopping Brute-force Logins Against WordPress</a></li>
<li><a href="http://www.inmotionhosting.com/support/website/wordpress/lock-down-wordpress-admin-login-with-htaccess">Lock down WordPress admin login with .htaccess</a></li>
<li><a href="http://halfelf.org/2013/wp-login-protection-htaccess/">WordPress Login Protection With .htacces</a></li>
</ul>
<p>Definitely interested in hearing if anyone else has any other good ideas around how to approach this issue or has any tips from me as I am certainly no security expert. However after the uptime for my server has definitely improved over the last while with all of this helping to reduce WordPress hacker attacks on this blog.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>22 tips for managing successful Agile projects</title>
    <link href="https://blog.david-jensen.com/managing-successful-agile-projects-22-tips/"/>
    <updated>2013-08-18T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/managing-successful-agile-projects-22-tips/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/managing-successful-agile-projects-22-tips/listen-to-this-wall.jpg"></a></p>
<p>In the past year I have run two large successful agile projects that have delivered software using the <a href="http://en.wikipedia.org/wiki/Scrum_(software_development)" title="Scrum">Scrum</a> methodology to build a minimum viable product (MVP) and then transitioned to <a href="http://en.wikipedia.org/wiki/Kanban_(development)" title="Kanban">Kanban</a> once they have gone live. The first one was the <a href="http://metro.co.uk" title="Metro.co.uk">Metro.co.uk</a> responsive redesign and CMS migration which was delivered on time and under budget. Since going live it has been quickly iterated to deliver solid mobile and overall traffic growth for Metro. The second project is the <a href="http://casino.metroplay.co.uk" title="Metro Play Casino">Metro Play Casino</a> which delivered its MVP as part of a large program of work that required us to get a fully regulated offshore gambling business started. This is now ahead of budgeted expectations and we are currently scoping the next phase of development. During both of these projects there have been some ups and downs but overall it has been a really positive experience. I thought I would share some tips that I have collated whilst managing these projects successfully using agile methodologies.</p>
<ol>
<li>Initially just define a few clear high level goals to measure success that allow detail to be filled in at the appropriate time.</li>
<li>Start prototyping as early as possible, learning by doing is the most effective way to figure out what to do and also what not to do. Being able to actually use something as early as possible is very important. Even if this means releasing something different than your end goal.</li>
<li>Don't break down every story in the beginning and add it up to find out how long the project is going to take, this will just leave you with an unmanageable backlog and most of the stories will be out of date by the time you come to develop them. We have found that the best approach is to get a group of experts in the room and play planning poker for the project as Dan North suggests calling it <a href="http://dannorth.net/2013/08/08/blink-estimation/" title="Blink Esitmation">Blink Estimation</a>.</li>
<li>Don't be afraid to pivot your MVP or technology choices if the learning that you gather points in slightly different direction than you first thought. Knowing what you don't want is as important as knowing what you want.</li>
<li>Clear and consistent goals facilitate quicker decision making. These enable decisions to be made based on logic and this decisioning can be distributed around the team and post validated. Any single point of decision making is going to really slow things down, especially important in the last couple of iterations.</li>
<li>If you are still developing a lot of new functionality in the last sprint be worried. Also leave a little bit at the end to tie it all together as things always pop up that you didn't plan for.</li>
<li>A more traditional Project Management layer can really help with external vendors and internal communication. Keep project plans at the highest possible level for visibility and better decision making especially on dependencies.</li>
<li>Change your process, change it again. Retrospectives are really key to this process so don't forget to have them after every sprint. Be agile about your process.</li>
<li>Quite often order comes from short periods of carefully orchestrated chaos, these can help teams form by giving people common frustrations. Listening to these and then adapting your process to remove them helps the team to feel empowered.</li>
<li>Get onto your production environment as soon as possible, no matter how similar other environments are they are never the same and issues will come out at this stage.</li>
<li>Get developers and the business talking directly if at all possible. Learning together through structured conversation delivers the best business value. These can be facilitated by a Business Analyst or Product Owner but they should not always be in the middle as the lack of knowledge transfer will harm the project. This is especially true when dealing with multiple stakeholders.</li>
<li>Bite off the biggest unknowns first and work on them to make them knowns. The best way to do this is to release something early and get real people to use your product. This doesn't need to be MVP but a Minimum Learning Product that delivers some value to end users.</li>
<li>You can assemble a group of people but it takes time and effort to form a team. Setting achievable goals and then ensuring they are delivered with a sprinkling of pressure early is a great way to prepare for the final few sprints.</li>
<li>Restrictions bring out peoples creativity.</li>
<li>In my opinion design should be emergent as should architecture, initially go with the most established patterns however you need to give the team time to fix things if they turn out to no longer be the right choice. This allows you to focus on actual problems rather than solving ones you only think you have.</li>
<li>Automated testing should focus on smoke tests and high level indicators when things are rapidly changing.</li>
<li>Automate builds and deployments in phase 0 for maximum payback.</li>
<li>Constantly engage the business to make them define the problems they are trying to solve and then work together on the right solution for the project and the business in iterative steps.</li>
<li>If you are going to take any risks with the project take those decisions at the latest possible point.</li>
<li>Celebrate the team and their successes.</li>
<li>Things will change constantly so learn to embrace it and hopefully get to the place where you enjoy it. If you have problems detailed rather than solutions then these can then be adapted as you learn.</li>
<li>Simple things you haven't done before are complicated to execute. Do not under estimate... or fall into the planning fallacy. Build complexity in over time.</li>
</ol>
<h2>Conclusion</h2>
<p>Managing successful agile projects is something that can deliver serious business benefit if done with the right approach. The constant feedback that is available allows iterative learning and if your environment is setup to handle this will allow you to be very nimble. Quite often agile is an approach amongst a sea of different project management methodologies and I believe that if adapted properly to your environment can bring real benefits to most projects.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Vrsus: &quot;The future of real time voting&quot; - DMGT Hackathon 2013</title>
    <link href="https://blog.david-jensen.com/vrsus-voting-dmgt-hackathon/"/>
    <updated>2013-05-31T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/vrsus-voting-dmgt-hackathon/</id>
    <content type="html"><![CDATA[
      <p>About six months ago I was sitting in a CTO meeting across DMGT and they were trying to come up with ways that we could improve collaboration across the group. After a few suggestions around wiki based API pages I came up with the idea to run a Hackathon. In my experience the best way to get geeks to know each other is let them build stuff together. This idea stuck and luckily <a href="https://plus.google.com/u/1/114386853686754719352/posts" title="Oliver Parke">Oliver Parke</a> had sometime on his hands and got the job of organising it all. We were very fortunate to be able to get the <a href="http://www.campuslondon.com/workspace/" title="Campus London Workspace">Campus London Workspace</a> to hold the event which is a hot bed of startups and geekery. The event was run on the 23rd and 24th of May and included technical people from businesses across DMGT including:</p>
<ul>
<li>Metro</li>
<li>Mail Online</li>
<li>Euromoney</li>
<li>dmg::media Sprint Suite / Dev Lab</li>
<li>Landmark</li>
<li>Evenbase</li>
<li>Broadbean</li>
<li>Wowcher</li>
</ul>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/Haribo-Fueled-Hacking.jpg" alt="Haribo Fueled Hacking"></p>
<p>I was fortunate enough to also be able to participate in Haribo fuelled hacking and below is an overview of what we built and how we approached the whole event.</p>
<h2>Vrsus: The future of real time voting</h2>
<p>Trying to find a group in the initial hustle of the team forming stage was easier than I thought. My initial idea was something based around real time analytics but this quickly morphed into a real time voting tool to decide which the best cats on the internet are. The great thing about the real time approach was a chance for us to use a load of new technologies. So the dream team that we ended up with consisted of the following:</p>
<ul>
<li>Mary Morgan (Euromoney Institutional Investor)</li>
<li>Frédéric Occédat (Mail Online)</li>
<li>Panagiotis Albanis (Metro)</li>
<li>George Old (dmg::media)</li>
<li>Me (Metro)</li>
</ul>
<p>Once we had a general direction with regards to online voting we had an hour design session around our flip-board to try to conceptualise the flow through our app and what screens and actions would be necessary. This gave us a decent enough understanding of the requirements to put together a technology stack which consisted of the following tiers:</p>
<ul>
<li>Amazon EC2 Ubuntu Instance</li>
<li><a href="http://twitter.github.io/bootstrap/" title="Twitter Bootstrap">Twitter Bootstrap</a></li>
<li><a href="http://angularjs.org" title="Angular.js">Angular.js</a></li>
<li><a href="http://socket.io" title="Socket.io">Socket.io</a></li>
<li><a href="http://expressjs.com" title="Express">Express</a></li>
<li><a href="http://nodejs.org" title="Node.js">Node.js</a></li>
<li><a href="http://redis.io" title="Redis">Redis</a></li>
</ul>
<p>As we wanted to be real-time and socket based most of the stack chose itself and we thought that Redis would provide a simple way of storing the data and retrieving the post via score. At this stage we started to get down to the detail of building the initial flows around being able to submit images for voting on.</p>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/us-vrsus-them-new-post.png" alt="us vrsus them new post"></p>
<p>I also started work on setting up the EC2 instance so we could easily pull from GitHub and keep the server running. There were a few things that I need to do in order to get the ports forwarded to HTTP and the Node process running in the background for which I used the following:</p>
<ul>
<li><a href="https://github.com/nodejitsu/forever" title="Forever">Forever</a> - makes Node.js run as a background process</li>
<li><a href="http://www.ubuntugeek.com/rinetd-redirects-tcp-connections-from-one-ip-address-and-port-to-another.html" title="Rinetd">Rinetd</a> - allows port forwarding on Linux so Node can run on port 80 and sockets on 8080</li>
</ul>
<p>Next steps were to get all the pages setup and the logo done which took the rest of the evening.</p>
<p>Coming in the next day first thing we sorted was our Kanban board to get everyone working on the different bits that were required. This worked well through out the day as we finished the following screens.</p>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/you-vrsus-me-home.png" alt="you vrsus me home"></p>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/you-vrsus-me-category.png" alt="you vrsus me category"></p>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/us-vrsus-them-sub-category.png" alt="us vrsus them sub-category"></p>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/us-vrsus-them-rank-page.png" alt="us vrsus them sub-category"></p>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/you-vrsus-me-vote.png" alt="you vrsus me vote"></p>
<p>I also managed to procure the domain name vrsus.me and then added the subdomain <a href="http://you.vrsus.me" title="Vrsus">you.vrsus.me</a> to it to give it a bit of entertainment. The second day disappeared far to fast and I focused on stripping down the homepage to be nice and simple and also on the create page the ability to preview the image as soon as it has been added using sockets. We decided to against our idea of being able to enter any URL and for us to go and scrape the Open Graph or Twitter tags from it to get the images from the page to just entering a URL of an image.</p>
<p>This proved to be a good idea as it took us the rest of the day just to get the basic flow working, due to Redis not having any relational abilities there it took a bit of time to figure out how to store both the complex hash around the upload as well as the score after voting. The ability for the list to change order in real time also came right down to the wire and although there isn't a fancy animation the list view is socket based and will change order when votes come in which I think adds a lot to the application.</p>
<p>It was then time to give a presentation of how we had approached everything and I had managed to knock up the below in Prezi.</p>
<iframe src="http://prezi.com/embed/xmymjwseyyzo/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&features=undefined&disabled_features=undefined" height="400" width="100%" frameborder="0"></iframe>
<p>We won the 'Most Technically Impressive' category overall.</p>
<h2>Future Ideas</h2>
<p>If we were to have some more time to develop this application into something more fully fledged I think these are the area's that we would focus on.</p>
<ul>
<li>Ability to post any url and vote on it</li>
<li>Social integrations</li>
<li>Ability to put sponsored posts in it</li>
<li>General responsive and cross browser performance</li>
<li>Improvements to the animation</li>
<li>Tracking</li>
</ul>
<p>I think that Vrsus could be utilised across DMGT in many different ways apart from just showing the best cat beards on the internet. Having a real time voting system that people could submit content to that allowed the best to rise to the top based on user interaction would be a valuable asset in my opinion.</p>
<p>If you are interested in having a look at the code you can see it on <a href="https://github.com/panos2point0/versus" title="Vrsus Github">GitHub</a> and the url <a href="http://you.vrsus.me" title="Vrsus">you.vrsus.me</a> is still live and will be so for the next month or so.</p>
<h2>Video</h2>
<iframe src="http://player.vimeo.com/video/67164555" height="281" width="500" allowfullscreen="" frameborder="0"></iframe>
<p><a href="http://vimeo.com/67164555">DMGT Hackathon - Google Campus</a> from <a href="http://vimeo.com/danbuckjoyceofilms">Dan Buck Joyce - OFILMS</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<h2>Photos</h2>
<p><img src="/assets/images/vrsus-voting-dmgt-hackathon/logo2.png" alt="Vs Logo"></p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Changing the Paradigm with Swipe</title>
    <link href="https://blog.david-jensen.com/metro-changing-paradigm-swipe/"/>
    <updated>2013-05-22T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/metro-changing-paradigm-swipe/</id>
    <content type="html"><![CDATA[
      <p>I was very fortunate to attend the 2013 <a href="http://vip.wordpress.com/vip-workshop-2013/" title="WordPress VIP Workshop 2013">WordPress VIP Developer conference</a> in Napa Valley this year. It was great to meet all of the people who use WordPress at scale across the media space and the lovely people behind it all at Automattic. Also crazy to see that the average development team size for someone on WordPress VIP is 2-3, considering many of these sites are serving millions of uniques a day that is incredibly lean.</p>
<p>I was asked to give a lightening talk (less than 5 minutes) on a subject and I decided I would give a quick overview of how we have approached building Swipe into metro.co.uk. This seemed to go down quite well though <a href="http://qz.com" title="Quartz">qz.com</a> were on after me and what they have done with their front end is even more impressive. I thought it would be a nice idea to put my slide deck up somewhere for viewing.</p>
<p>UPDATE: Metro have decided to remove swipe from Metro.co.uk for <a href="http://metro.co.uk/2013/10/01/why-swipe-has-been-removed-from-metro-co-uk-and-what-the-future-holds-4110488/" title="Why swipe has been removed from Metro">these</a> reasons.</p>
<p>One of the other talks the previous day was by <a href="https://twitter.com/yurivictor" title="Yuri Victor">Yuri Victor</a> on <a href="http://yurivictor.com/2013/01/09/why-the-washington-post-uses-wordpress/" title="Why the Washington Post uses WordPress">why the Washington Post uses WordPress</a> and if you haven't already seem it then it is definitely worth the visit even for the typography alone.</p>
<p>Other great notes from the few days were to use the following for WordPress debugging.</p>
<ul>
<li><a href="http://wordpress.org/plugins/debug-bar/">Debug Bar</a></li>
<li><a href="http://wordpress.org/plugins/debug-bar-console/">Debug Bar Console</a></li>
<li><a href="http://wordpress.org/plugins/debug-bar-cron/">Debug Bar Cron</a></li>
</ul>
<p>Also use <a href="http://http://gruntjs.com/">Grunt</a> to automate the use of these two libraries for image optimisation.</p>
<ul>
<li><a href="http://freecode.com/projects/jpegoptim">jpegoptim</a></li>
<li><a href="http://optipng.sourceforge.net">optipng</a></li>
</ul>
<p>Generating fonts to help reduce images/sprites can be a good idea or just use <a href="http://genericons.com/">Genericons</a> which have been done for you. Also I found out that script tags on a page are completely blocking.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How to use Atlassian Jira with Greenhopper to manage multiple Backlogs</title>
    <link href="https://blog.david-jensen.com/greenhopper-multiple-backlogs-jira-product-owners/"/>
    <updated>2013-04-01T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/greenhopper-multiple-backlogs-jira-product-owners/</id>
    <content type="html"><![CDATA[
      <p>At <a href="http://metro.co.uk" title="Metro">Metro</a> our development project has multiple <a href="http://www.mountaingoatsoftware.com/scrum/product-owner" title="Product Owner">product owners</a> who each have their own backlog and want to prioritise them separately using <a href="http://www.atlassian.com/software/greenhopper/overview" title="Greenhopper">Greenhopper's</a> drag and drop interface. We didn't want to create multiple projects to enable this and Greenhopper's multiple backlogs support for a single project is something that had previously eluded me. <a href="https://twitter.com/AdeShokoya" title="Ade Shokoya">Ade Shokoya</a> who was our business analyst came up with the idea of creating an additional Kanban rapid board with product owner based swimlanes to achieve this. We now have one Kanban rapid board to manage the product owner backlogs and one to manage development priorities. They share a column which allow tasks to flow easily from one to the other.</p>
<p>We use components within our Jira project to categorise tasks by the business area and product owner that they deliver value for. Each component allows you to setup a default owner and this ensures that they are notified when any tickets are added or amended. We created an additional Kanban rapid board specifically for backlog management and added &quot;Backlog&quot;, &quot;To Do&quot; and &quot;Scheduled for Development&quot; columns to this. We then enabled swimlanes based on components so each of the individual backlogs can be prioritised separately within these. We also utilise quick filters based on component to allow each product owner to only see their tickets on the rapid board. As the filters are URL based this allows each product owner to have a browser bookmark to take them straight to their backlog.</p>
<h2><strong>Setup Swimlanes per Component</strong></h2>
<p><a href="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Rapid-Board-Swimlanes.png"></a></p>
<h2><strong>Setup Quick Filter per Component</strong></h2>
<p><a href="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Rapid-Board-Quick-Filters.png"><img src="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Rapid-Board-Quick-Filters-1024x288.png" alt="Greenhopper Multiple Backlogs Rapid Board Quick Filters"></a></p>
<h2><strong>Greenhopper Multiple Backlogs Kanban Rapid Board with Swimlanes and Quick Filters</strong></h2>
<p><a href="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Greenhopper-Multiple-Backlog-Rapid-Board.png"><img src="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Greenhopper-Multiple-Backlog-Rapid-Board-1024x447.png" alt="Greenhopper Multiple Backlog Product Owner Board"></a></p>
<p>Getting the business engaged with development process and priorities in Jira is a long term project of mine (as otherwise I am the only person who manages the board). The best way that I have found to do this is hold specific product owner stand ups twice a week where we have a look at the work in progress and discuss what the priorities are for the items about to move into the development stream. We have this around the TV that has our development Kanban rapid board displayed on it and can quickly switch between that and the backlog view. This allows each of the product owners to get a good view of overall priorities and where their requests fit into that. They also see how the process works and have an opportunity to provide feedback. This is complimented by a meeting every other week where we look at how each idea is delivering value based on performance data and then decide whether we do more or less of this based on our overall strategy.</p>
<p>Having multiple Rapid Boards for a more complicated flow that keeps each of the boards simple is one of the best moves that we have made. We are also now using a separate board to tightly manage our testing and release process as we have multiple environments and stages that overcomplicate the main board. Greenhopper has been really good at adding new features and streamlining their existing ones to provide a great way of managing the different stages of the project in a single dashboard.</p>
<h2><strong>Metro.co.uk Greenhopper Kanban Rapid Board Dev Board</strong></h2>
<p><a href="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Development-Board.png"><img src="/assets/images/greenhopper-multiple-backlogs-jira-product-owners/Development-Board-1024x672.png" alt="Metro Greenhopper Development Board"></a></p>
<h2>Background</h2>
<p>I have been using the <a href="http://www.atlassian.com" title="Atlassian">Atlassian</a> stack including <a href="http://www.atlassian.com/software/jira/overview" title="Jira">Jira</a> and <a href="http://www.atlassian.com/software/greenhopper/overview" title="Greenhopper">Greenhopper</a> to manage multiple Agile projects using its Scrum templates over the last three years. The great thing about Jira (and at times the most frustrating thing) is that it is pretty much infinitely configurable and Greenhopper gives a great drag and drop interface for Scrum and Kanban setups. Personally I don't have the time to manage both an online system and a paper based post it system so we moved everything into Jira and got a 42&quot; television which is used for displaying boards during standups and as an information radiator during the day.</p>
<p>During the minimum viable product (MVP) phase of the metro.co.uk CMS migration we had a nice simple setup of Greenhopper utilising its Scrum template with a dedicated Business Analyst (BA) who managed the backlog. However he was a project resource and his contract was about to come to an end, we had also shifted from using Scurm to using Kanban but were initially struggling with the flow from the large backlog left over from the project.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Scrum to Kanban - 10 Lessons learnt from migrating</title>
    <link href="https://blog.david-jensen.com/scrum-to-kanban-10-lessons-migrate/"/>
    <updated>2013-03-14T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/scrum-to-kanban-10-lessons-migrate/</id>
    <content type="html"><![CDATA[
      <p>The initial phase of the responsive redesign of <a href="http://metro.co.uk" title="metro.co.uk">metro.co.uk</a> was a project that spanned 14 two weeks sprints. At the end of the sprint cycles we released a minimum viable product which we had to rapidly iterate to fill in some gaps that didn't quite make the last mad dash. During this process we migrated from <a href="http://www.scrumalliance.org/learn_about_scrum" title="What is Scrum">Scrum</a> to <a href="http://en.wikipedia.org/wiki/Kanban_(development)" title="Kanban">Kanban</a> as the pressure to get things fixed was as constant as the changing priority of requirements. Having been through this process I am not sure that I could go back to Sprints for the business as usual part of a project. However we have learnt a lot over the last few months and I thought I would share my lessons learnt in case you are also interested in making this transition.</p>
<h2>Scrum to Kanban</h2>
<ol>
<li>In order to release as often as possible, focus on smoke tests and automation of deployments between environments. Usually this requires a pretty complex setup that will take some time to find the optimal process.</li>
<li>Use <a href="http://martinfowler.com/bliki/FeatureBranch.html" title="feature branches">feature branches</a> to allow small changes to be encapsulated and tested on each environment. This can take some getting used to but the pay off is well worth it.</li>
<li>Don't under estimate the power of a Dev Ops culture even if you don't have a specific person for this role empowering both developers and testers to have the time to set everything up correctly will save you time and errors in the future.</li>
<li>Break things down to the smallest possible developments based on the feedback that they can provide to avoid blockages. This doesn't mean large projects can't be done but should be packaged in multiple small releases.</li>
<li>Limit work in progress (WIP) as well as items on the backlog. A large backlog is usually the most inefficient part of this process. No longer can it be the dumping ground for ground for random ideas. If it isn't done within three months I auto delete and see what people complain about.</li>
<li>Hold product performance meetings rather than sprint planning. Bring feedback and measurements and invite both business and development resources and let the data win the arguments. Setting the measurements up takes a while but they payoff of everyone looking at the right metrics is worth it. You will also need a solid goal to be aiming at.</li>
<li>Much more conversation needed on a regular basis, we now hold product owner stand ups twice a week as talking every other week isn't enough when you are moving that fast.</li>
<li>Talk about problems define small solutions to provide learning then iterate.</li>
<li>Whiteboards are your best friend. All of the walls in our new office are whiteboards and it really helps quick brainstorms. Also allows you to leave complex problems in visible place to revisit over time until solutions become clear.</li>
<li>Don't forget retrospectives.</li>
</ol>
<h2>Conclusion</h2>
<p>Now that we have been running with Kanban for over three months it is amazing how much faster the team has become. Breaking things down into small pieces is probably the biggest skill that is needed to keep the process efficient. Also ensuring that the business are engaged throughout the process has taken some time but the benefit is huge. Agility has also increased as now when we find an issue or discover a new key piece of information you are able to act on it straight away rather than waiting until the next planning meeting. If you are interested in reading in more detail about Scrum vs Kanban then I highly recommend reading <a href="http://www.infoq.com/minibooks/kanban-scrum-minibook" title="Scrum vs Kanban">Scrum vs Kanban</a> by Henrik Kniberg.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How to speed up WordPress Apache</title>
    <link href="https://blog.david-jensen.com/speed-up-wordpress-apache/"/>
    <updated>2013-03-12T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/speed-up-wordpress-apache/</id>
    <content type="html"><![CDATA[
      <p>I spent this morning running the <a href="https://chrome.google.com/webstore/detail/pagespeed-insights-by-goo/gplegfbjlmmehdoakndmohflojccocli" title="Google Chrome Pagespeed Chrome">PageSpeed Insights</a> tool in Google Chrome over this website and it came back with some good tips on how to speed up WordPress Apache to make this site run faster. I thought I would share how I approached making the recommended changes below.</p>
<p>The first critical issue that it threw up was to turn KeepAlive On, this means that Apache keeps the session alive to transfer multiples files. This reduces the latency as each new request for the multiple files that makes up a web page don't have the overhead of opening and closing a connection. I found this great overview of the options <a href="http://abdussamad.com/archives/169-Apache-optimization:-KeepAlive-On-or-Off.html" title="KeepAlive Off or On">here</a> which is worth reading if you want more details.</p>
<p>I then made the following changes to my /etc/httpd/conf/httpd.conf</p>
<pre><code class="language-apache">#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to &quot;Off&quot; to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 50

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 3
</code></pre>
<p>The second critical issue was a lack of compression so I needed to turn compression on and then ensure that all of the file types that benefit from compression were enabled with <a href="http://httpd.apache.org/docs/2.2/mod/mod_deflate.html" title="mod_deflate">mod_deflate</a>.</p>
<pre><code class="language-apache">#
# AddEncoding allows you to have certain browsers uncompress
# information on the fly. Note: Not all browsers support this.
# Despite the name similarity, the following Add* directives have nothing
# to do with the FancyIndexing customization directives above.
#
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz

&lt;FilesMatch &quot;\.(php|css|html?|xml|txt|js|pl)$&quot;&gt;
SetOutputFilter DEFLATE
&lt;/FilesMatch&gt;
</code></pre>
<p>The next issue that it identified was a lack of browser caching so I updated my .htaccess file to ensure that files that could be cached by the browser would be as recommended in this <a href="http://thesiteedge.com/leveraging-browser-caching-with-htaccess-in-wordpress/" title="Browser caching .htaccess WordPress">post</a>.</p>
<pre><code class="language-apache">## EXPIRES CACHING ##

ExpiresActive On
ExpiresByType image/jpg &quot;access 1 year&quot;
ExpiresByType image/jpeg &quot;access 1 year&quot;
ExpiresByType image/gif &quot;access 1 year&quot;
ExpiresByType image/png &quot;access 1 year&quot;
ExpiresByType text/css &quot;access 1 month&quot;
ExpiresByType application/pdf &quot;access 1 month&quot;
ExpiresByType text/x-javascript &quot;access 1 month&quot;
ExpiresByType application/x-shockwave-flash &quot;access 1 month&quot;
ExpiresByType image/x-icon &quot;access 1 year&quot;
ExpiresDefault &quot;access 2 days&quot;

## EXPIRES CACHING ##
</code></pre>
<p>Finally having spent some time on the Google PageSpeed website I saw they had developed the <a href="https://developers.google.com/speed/docs/mod_pagespeed/download" title="mod_pagespeed">mod_pagespeed</a> Apache module which combines a whole load of Apache web server performance best practices into a single install.</p>
<pre><code class="language-bash">wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_i386.rpm
sudo rpm -U mod-pagespeed-*.rpm
</code></pre>
<p>Finally I reran PageSpeed Insights and got an overall PageSpeed Score of 94 (out of 100) which was great for a couple of hours works to really speed up WordPress Apache.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Lean Fridays: Business idea validation done at scale</title>
    <link href="https://blog.david-jensen.com/business-idea-validation/"/>
    <updated>2013-03-08T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/business-idea-validation/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/business-idea-validation/idea.jpg"></a> This is the second time that I have been through the process of writing a story of how I think that the company I work for should evolve over the next 18 months. I previously <a href="/build-measure-learn-iterate-vision-agile-future/" title="Build, Measure, Learn, Iterate">wrote</a> about how I thought this would work out for Metro and it is amazing how much of that has actually happened. This story was written at a <a href="http://www.dmgt.co.uk/" title="DMGT">DMGT</a> level with a focus on how we solve the innovation challenges that a corporation of this size faces. My main premise is that we already have a lot of good ideas being generated but we are not so good at knowing which ones to invest time and money into. Business idea validation usually seems to take a back seat to idea generation but I think that this is the wrong way of looking things. These opinions and ideas are purely mine and don't reflect the views of anyone at Metro or DMGT. It will be interesting to see how this story plays out over the next 18 months as I have a lot less influence at this level than I did with Metro's. I have really come to respect story telling as a very powerful way to drive business change, <a href="http://www.stevedenning.com/site/Default.aspx" title="Steve Denning">Steve Denning</a> explains this very well in the article &quot;<a href="http://www.forbes.com/sites/stevedenning/2012/03/09/the-science-of-storytelling/" title="Science of storytelling">The science behind story telling</a>&quot;. The setting for the below is an induction day for a set of new recruits, the below is only my part of the story of which there were six parts.</p>
<h2>My story to come</h2>
<p>As you have just heard A+ Media’s digital revenue has recently surpassed their newspaper revenue. This rapid evolution was largely driven by a change in organisational thinking. The focus moved from opinion based decision making to a factual based iterative approach. This increased the speed of innovation and decreased the costs and risks of trying new things. The process was a disruptive one to the wider business but it was recognised that it was better to disrupt ourselves than be disrupted. Management started by setting goals that focused on digital revenue across the whole of A+ Media. They then used a data driven model to validate a large number of ideas around new digital revenue opportunities. For each revenue opportunity they formed a customer based hypothesis that they used their considerable client contacts and existing audience to quickly validate. Next decisions were then based on this real world feedback. A+ Media have used this way thinking to foster a culture of constant innovation from iterative learning. The knowledge that data will win any argument over ego was a critical factor in mobilising the whole of A+ Media behind their digital goals. So I guess you are thinking what does this have to do with me on your induction day? Well you will be taught these techniques and they will help you to shape both the future of A+ Media and each of your respective organisations. This process is called Lean Friday’s and there is a dedicated team who organise and facilitate these. They will be in contact soon, as each of you will be involved in at least one of these sessions a quarter. Lean Fridays are our idea validation process where we take a cross functional group of people and get them to validate our ideas around digital revenue opportunities. In a competition at the end of every month validated ideas are chosen for further data driven development. The team that validated the idea is also given the opportunity to continue to be involved. Idea generation and selection is taken care of by a market based approach. Every employee is given the ability to submit an idea in Salesforce for consideration. They are also given a set amount of A+ currency to invest in ideas that they think will provide the most amount of value. Ideas are ranked in Salesforce based on the amount of investment in them. When a successfully validated idea is turned into revenue then a small percentage of profit is given back to both the initial creator and investors of the idea. They are also given additional A+ currency to invest again. An example of this was: “Stephan Fowler a developer from Metro who came up with the idea to create a marketplace for commercial content creation. Internal knowledge and testing validated how to structure this so editorial would be correctly incentivised and clients validated how much and what they would be willing to pay in trail runs. We then quickly developed an internal prototype using open source software. Over time this was refined and then finally released into the wider marketplace. It has since created over £10 million of profit and Stephan received £10,000 for this.” Highly visible examples like this have ensured that everyone is interested in the generation and validation of ideas and put constant innovation at the heart of our culture. Good luck with your ideas and investments if you would like to know any more about the process please don’t hesitate to ask.</p>
<h2>Conclusion</h2>
<p>Waste is a huge problem for large modern organisations, usually business models are optimised over time to reduce that waste. I believe that by ensuring the right validation of ideas we can reduce the waste that occurs at the earliest stages of new business model generation. Lean Friday's would be an approach that I believe that would work to do business idea validation at scale. I also believe that they would solve one of the other problems that large organisations have which is communication. By bringing a group of people together around a common problem you can quickly learn how other parts of a large business work and gain some insight and knowledge which is very valuable. Technical companies have <a href="http://en.wikipedia.org/wiki/Hackathon" title="Hackathon">hack days</a> for this very reason and people like <a href="http://www.fastcompany.com/3002845/secrets-facebooks-legendary-hackathons-revealed" title="Facebook Hackathon">Facebook</a> and <a href="http://www.atlassian.com/company/about/shipit" title="Atlassian Hackathon">Atlassian</a> are already harnessing these approaches to massive business benefit.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>How I helped a group of technical people form a high performing team</title>
    <link href="https://blog.david-jensen.com/turn-technical-people-high-performing-team/"/>
    <updated>2013-02-24T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/turn-technical-people-high-performing-team/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/turn-technical-people-high-performing-team/blogs.jpg"></a> Another challenge that is faced early in projects is how to turn the talented group of individuals assembled into a high performing team. With the ambitious goals of <a href="/metro-responsive-swipe-website-launch/" title="Metro Responsive Swipe">the project</a> laid out it was essential that this was completed as early as possible. The best way I have found to do this is set a goal based around a set of restrictions that the team can only solve by working together. For the Metro WordPress project it was getting our responsive <a href="http://blogs.metro.co.uk" title="Metro Blogs">blogs</a> site live for use by editors and end users behind Akamai at the end of our third sprint. I think that the third sprint was a good time to do this as the team already had a basic understanding of the domain, technology, each other and process. I also took some time off right at the deadline as without me leading the project the team would need to work together and communicate more with each other. You need to empower individuals and if you are a leading figure by removing yourself you create the space for others to step up.</p>
<h2>Self Organisation</h2>
<p>You obviously also need motivated individuals, the right rewards and a clear achievable goal but when I came back in after the deadline you could almost feel the difference. The team had managed to deploy all the code but not quite configure Akamai correctly to deal with cached User Agents for the mobile site. They had self organised to get a far as they did and only an unknown consequence of a design decision stopped them from meeting the target. However the learning from this mistake ensured we made the right choice later in the project and avoided User Agent detection in favour of using widths. The restriction of time, platforms and approach ensured that they had a common frame of reference to approach the problem and organise around.</p>
<h2>Emergent Design and Technical Debt</h2>
<p>The team had also hacked a lot of things to meet the deadline which they were now all passionately complaining about. I am a big fan of emergent design where you let the pain points of a project show themselves before fixing. This was a great example of that and I then let the team use the rest of the week to clean up the technical debt and you could see that sealed the team's formation. If you let talented passionate people speak their mind together about constraints and then give them time to fix those issues you get what you actually need not what one person views as the best approach. However if you don't give the team time to clear the technical debt you will loose respect and all of the good work. They also wont feel empowered to make their own decisions in the future.</p>
<h2>Order comes out of Chaos</h2>
<p>Order comes out of chaos rather than overly thought order descending into chaos. Wrong assumptions made before problems were fully comprehended have derailed many other projects I have been involved in. Leaving all decisions to the last possible point when the maximum amount of learning has been completed is always a good idea. When people have a clear mental model of the problem rather than an out of date one from previous projects that they assume to be valid. As I mentioned earlier you need to insert chaos at the right time in the project as if it is done too early then you can lose more than you gain.</p>
<h2>High Performing Team</h2>
<p>To see the passion from everyone having made some compromises for a short term goal and their insistence that this could not continue I knew that this group of people was now a team. The learning that they had from self organising around a clear goal and solidarity against the technical debt showed they were well on their way to be a high performing team.</p>
<h2>Key Learnings</h2>
<ul>
<li>Constraints help creativity.</li>
<li>Clear goals help people self organise.</li>
<li>Removing a leader for a short period can help self organisation.</li>
<li>Allowing pain points to surface due to constraints makes people passionate.</li>
<li>Passionate people perform better if you then empower them by listening to their opinions and fix the technical debt.</li>
<li>The group needs a certain level of maturity before trying this approach.</li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>Planning for success when agile and traditional methodologies collide</title>
    <link href="https://blog.david-jensen.com/planning-for-success-agile-collide/"/>
    <updated>2013-02-16T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/planning-for-success-agile-collide/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/planning-for-success-agile-collide/overview.jpg"></a></p>
<p>As I previously <a href="/why-metro-chose-wordpress-vip-cms/" title="Why Metro chose WordPress VIP">wrote</a> Metro decided to use the WordPress VIP platform for their CMS and front end, this post will detail how we set about the initial part of the project to give it the best chance of success. Initially it was pretty daunting looking forwards 12 months with the sheer scale of the project and diverse set of stakeholders that would judge its success. During this time the development team would also be switching from Java to PHP, have to learn a new platform and completely change the user interface for all of the people who manage and interact with <a href="http://metro.co.uk" title="Metro.co.uk">Metro.co.uk</a> on a daily basis. We had a few whiteboard sessions to try and scope out the high level requirements and each time we &quot;peeled the onion&quot; the board filled up till our brains hurt.</p>
<h2>Minimum Learning Product</h2>
<p>However the great thing about WordPress is that you can run and install it yourself just as easily as use their on-line offerings. I realised that the biggest knowledge gap that we had was WordPress itself both how to develop themes to how to use it to publish articles. We then made one of the best decisions in my opinion of the whole project and decided that we would use an Amazon AWS instance to self-host WordPress and create <a href="http://blogs.metro.co.uk" title="Metro Blogs">blogs.metro.co.uk</a>. This would be a place that we would release real code to throughout most of the project which was able to be used as a prototype that didn't have the hangups of being the full site but would allow us to learn alongside the content team throughout the project. It took us two weeks to get our first release out and it was pretty damn basic, even with a large amount of on-line resources and a very talented team do not underestimate the complexities of learning a new system and programming language. We managed to get something out and get some really valuable early feedback from the business.</p>
<h2>Planning For Success</h2>
<p>It was also at this time that we started to think around how best to optimise the front end for the multitude of devices that were starting to grow into a sizeable part of our audience. <a href="http://coding.smashingmagazine.com/2011/01/12/guidelines-for-responsive-web-design/" title="What is Responsive Design">Responsive design</a> was starting to become a pattern for overcoming these problems and WordPress gave us the ability to focus more on the front end as the core CMS was already built for us. Again we had to learn a completely new way of approaching the front end so we did a phase of development on blogs where we could start to learn by building product. We now needed to move on to the initial planning phase. I think the key learning from this part of the project is to not plan too little and not plan too much.  There were some set milestones and we kept it very high level but the visibility that it gave us was very useful especially where external vendors timelines could impact our project. The biggest question was how long the development would take and to be honest we just chose a date so it would be delivered before the end of the calendar year that would give us 14 two week sprints. I think this approach is as good as any at this stage of the project as no matter how much thought and effort you will put into it you will be wildly wrong. All this time I had kept a single dedicated resource on the blogs project who was working on automating the deployment and tweaks based on feedback. The more time that your developers can be writing code during the project the better and automation is the right way to approach this.</p>
<h2>100+ Item Detailed Backlogs Are Unmanageable</h2>
<p><a href="/assets/images/planning-for-success-agile-collide/StoryMapping.jpg"><img src="/assets/images/planning-for-success-agile-collide/StoryMapping.jpg" alt="Metro.co.uk Story Mapping"></a></p>
<p>Now comes for what I perceived to be the biggest waste in the project. We spent a couple of weeks trying to map out all of the requirements in multiple day long meetings and then put everything in a massive backlog. We even did our best to provide story point estimates. However we knew so little about the how and WordPress provided so much functionality out of the box that it was just confusing. Having a backlog with over 100 items on it is unmanageable and as we were going through a steep learning curve requirements quickly became out of date but no one wanted to delete them. The struggle was the business wanting to know exactly what they would get in 10 months time. This fear of letting go of that knowledge is the biggest step in the transition to an agile mindset. By focusing on the high level problems you will solve rather than specific details you can start to bridge this gap. You can understand their fear in the context of multiple late previous development projects deployed by the previous team. Doing it all again I would only focus on details for the next 2-4 weeks with high levels goal for everything beyond that. Prioritise the bits to break down by amount of learning and risk to the project and get on with it.</p>
<h2>Don't Forget Retrospectives</h2>
<p>During this part of the process we decided to go with SCRUM as our project management methodology as its iterative approach fits well with traditional project plans. We tweaked our process at the end of almost every iteration until we got it to cause the least amount of pain. Our main learnings were around confusion born out of initially splitting stories into tasks for multiple people that had lack of a clear owner. We solved this by just having story tickets that one person would own at a time. We also struggled with the translation of business requirements through a Business Analyst (BA) to the backlog. The BA was an acting Product Owner and one that lacked the domain knowledge which made his a hard job. If your developers aren't talking to the business or a domain based Product Owner then they aren't learning and this lack of knowledge can create confusion. Confusion is a major waste of time in the early stages of a project. It also inhibits learning that is essential to gain momentum through the later stages of the project. This enables developers to make better decisions that can shorten feedback loops which leads to faster development speeds and less waste. This agility come from a common understanding of clear goals alongside validated learning. I now needed to hire some new people and build a team to get through the bulk of this project which I will cover later.</p>
<h2>Crossing The Chasm</h2>
<p>Gradually as we went through the project the business got more comfortable with reporting based on ability to hit the initially outlined goals and a clear view of where we were within the project plan. Planning for success helped us deliver this project on time and under budget.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>The story behind Metro&#39;s number one entry in Buzzfeed&#39;s best error pages on the Internet</title>
    <link href="https://blog.david-jensen.com/the-story-behind-buzzfeeds-best-error-pages-on-the-internet/"/>
    <updated>2013-02-12T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/the-story-behind-buzzfeeds-best-error-pages-on-the-internet/</id>
    <content type="html"><![CDATA[
      <p><a href="/assets/images/the-story-behind-buzzfeeds-best-error-pages-on-the-internet/404-funniest.jpg"></a></p>
<p>Over the past few years error pages of the Internet have got a lot more interesting. Page Not Found know as <a href="http://en.wikipedia.org/wiki/HTTP_404" title="HTTP 404">HTTP 404</a> has been at the front of this movement. Rather than the more staid errors of old developers have started to inject their own special kind of humour into them. I was really interested In the psychology behind these pages, I then read <a href="http://uxmag.com/articles/your-logo-is-making-me-sick" title="Your Logo Is Making Me Sick">&quot;Your Logo Is Making Me Sick&quot;</a> which explains that when people are angry with your brand the last thing you want to do is have your logo part of that negative experience.</p>
<blockquote>
<p>Every product will at some point encounter a critical error and/or force the user to wait. Don’t let those moments become synonymous with your brand.</p>
</blockquote>
<p>The other thing to note is the state of the project that this was developed at. We were aiming for a very aggressive <a href="http://en.wikipedia.org/wiki/Minimum_viable_product" title="Minimum Viable Product">MVP</a> release date and the whole team were really pushing hard for this. We knew we wouldn't get it all right straight away with over 300k articles to migrate from multiple previous CMS's and a completely <a href="/metro-responsive-swipe-website-launch/" title="Metro Responsive Website">new responsive front end</a>. I had spent the day browsing <a href="http://www.buzzfeed.com/expresident/animals-who-are-extremely-disappointed-in-you" title="33 Animals Who Are Extremely Disappointed In Yo">33 Animals Who Are Extremely Disappointed In You</a> to prepare myself for possible miss of the release date as the project was on a knife edge. Then it struck me for all those people that wouldn't quite make it to where they wanted why not give them something funny to look at to leave them with a slightly confused but happy feeling. Image rights can be a bit of a nightmare but Metro has some great content and having had a chat with the content team the <a href="http://metro.co.uk/2012/09/03/saturday-night-fever-dancing-polar-bear-struts-his-stuff-like-john-travolta-563975/" title="Dancing Polar Bear">dancing polar bear</a> was selected. The Sunday before the project as due to go live the team were in the office in a slightly silly mood and I happened to skate in that day to blow a few cobwebs out. GIMP came out and the dancing polar bear was born. He was later pimped out with a 404 chain just to complete the effect. I distinctly remember one of my team going surely this can't be the most important thing we have to work on right now. However when you have been banging your head against big problems for a week a break and something to take your mind off what you are doing is exactly what is needed. The day we went live we were monitoring 404 errors and suddenly saw our 404 page shoot to the top of our most read pages. We realised that it was being done on purpose to share on Twitter and from then on a <a href="http://metro.co.uk/404" title="Metro 404 Page">legend was born</a>. To get #1 on Buzzfeed's &quot;<a href="http://www.buzzfeed.com/awesomer/the-best-error-pages-on-the-internet" title="The 28 Best Error Pages On The Internet">The 28 Best Error Pages On The Internet</a>&quot; was just the icing on the cake. Thanks to <a href="https://twitter.com/stephanfowler" title="Stephan Fowler">@stephanfowler</a> for the GIMP skills.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Why Metro chose WordPress VIP for their CMS and front end</title>
    <link href="https://blog.david-jensen.com/why-metro-chose-wordpress-vip-cms/"/>
    <updated>2013-02-09T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/why-metro-chose-wordpress-vip-cms/</id>
    <content type="html"><![CDATA[
      <h2>Metro's existing CMS &quot;WPS&quot;</h2>
<p>When I joined Metro they were using a custom CMS that used <a href="https://developers.google.com/web-toolkit/" title="Google GWT">GWT</a> for the admin screens which wrote to a <a href="http://dev.day.com/docs/en/crx/2-0/getting_started/crx_concepts.html" title="What is CRX?">CRX</a> content repository and then used <a href="http://cocoon.apache.org/" title="Apache Cocoon">Cocoon</a> to pull fragments of XML out and parse them into HTML for the  front end via <a href="http://www.akamai.com/html/support/esi.html" title="ESI Akamai Includes">ESI</a> tags on <a href="http://www.akamai.com" title="Akamai's">Akamai</a>'s content delivery network (<a href="http://en.wikipedia.org/wiki/Content_delivery_network" title="What is CDN?">CDN</a>). It was an incredibly complicated system that had started with big promises about the &quot;future of semantic publishing&quot; and was originally planned to be rolled out across Associated Newspapers as the default CMS. However the internal department which was in charge of development became Mail Online, the people who wrote their dissertation on it left the company and the project was left to myself and the team at Metro to stabilise and maintain. During this time it was taking on average three months to get a developer up to speed with the platform and our ability to move quickly was pretty much non existent. The implementation of CRX had also been setup by people who didn't really understand it's inner workings properly. Having spent most of a holiday I had on the phone trying to stabilise the system I came back with the knowledge that things had to change. At the same time my boss Jamie Walters had used WordPress.com to setup a blog that had a mobile, tablet and desktop version in less than 3o minutes.</p>
<h2>CMS Selection Process</h2>
<p>We then went into a large scale look at all of the publishing based CMS systems and quickly realised that spending a lot of money to tie yourself into a vendor who's main goal is to make money from you by making you upgrade every few years would not be the way forward. As part of that process we saw that <a href="http://automattic.com/" title="Automattic">Automattic</a> the company behind WordPress.com had a <a href="http://vip.wordpress.com/" title="WordPress VIP">VIP</a> service that allowed you to utilise the might of their WordPress.com infrastructure  as a platform for publishing. This would allow the Metro development to focus on the user experience of news and be able to leverage all of the open source knowledge around the subject.</p>
<p><img src="/assets/images/why-metro-chose-wordpress-vip-cms/2012.jpg" alt="Metro.co.uk in 2012"></p>
<p>WordPress VIP's pricing structure was also very nice and simple with unlimited traffic, bandwidth and storage and a set charge additional charge depending on the support tier you require. They also helped out with our content migration and we ended up going with a high level of support throughout our build and then dropped it down once we had gone live. They also run six data centres in active-active mode so you don't need to worry about disaster recovery. Automatticians are a very dedicated bunch and are distributed throughout the world which really helps when working on large scale projects such as this. They also have the ability to change the WordPress platform to ensure that you can achieve your goals. One thing to consider is that they check every line of code before it goes up on their platform both before your code goes live and once it is up and running. WordPress is also constantly being updated by the large worldwide community it has behind it and a lot of the commodity items that a websites needs are taken care of for you. It had to go to the investment board twice but just before the second time CRX melted down and for five days straight we could only run it for 20 minutes out of every hour to update our Akamai cache and keep the site looking somewhat fresh. This couldn't have come at a better time in the decision making process and we got the sign off we needed.</p>
<p><img src="/assets/images/why-metro-chose-wordpress-vip-cms/2013.jpg" alt="Metro.co.uk in 2013 on the WordPress VIP platform"></p>
<h2>Things worth considering when switching to WordPress VIP</h2>
<p>We are now two months post our go live date and I can safely say that utilising the WordPress VIP platform has been a really positive experience. There are a few things that are worth bearing in mind however.</p>
<ul>
<li>WordPress.com does not support the www subdomain so we are now metro.co.uk rather than www.metro.co.uk.</li>
<li>Initial Automattic code review can take 6-8 weeks to fully complete.</li>
<li>Every time you make a change to your theme it needs to be approved by an Automattician (most completed within an hour and you can request faster in an emergency).</li>
<li>WordPress.com does not support the passing of query strings around the application due to their caching setup.</li>
<li>It is pretty hard to get your local and test builds similar to WordPress.com so get your code on their servers as soon as possible.</li>
<li>The WordPress platform changes pretty much every day which has great benefits but you need to stay on top of updates.</li>
<li>As most people who build WordPress sites do it for multiple clients it took us a long time to find someone to join on a permanent basis with the right level of skill.</li>
<li>If you have any resource managing your servers currently then they will be less busy.</li>
<li>WordPress VIP also offer self hosted help if you already have everything setup.</li>
</ul>
<p>For how we approached the project from a project management point of view read some more <a href="/turn-technical-people-high-performing-team/" title="Planning for success">here</a>. Links:</p>
<ul>
<li><a href="http://vip.wordpress.com/2012/12/11/metro-uk-migrates-to-wordpress/" title="WordPress VIP Metro Migration">WordPress VIP Metro Migration</a></li>
<li><a href="http://wpdaily.co/metro-co-uk/" title="UK’S 3RD LARGEST NEWSPAPER GOES WORDPRESS VIP">WP Daily: UK’S 3RD LARGEST NEWSPAPER GOES WORDPRESS VIP</a></li>
<li><a href="/metro-responsive-swipe-website-launch/" title="Metro Responsive Website Launch now with added Swipe">Metro Responsive Website Launch now with added Swipe</a></li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>WordPress Multisite Change Domain Name of Subsite using SQL</title>
    <link href="https://blog.david-jensen.com/wordpress-multisite-change-domain-name-sql/"/>
    <updated>2012-11-18T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/wordpress-multisite-change-domain-name-sql/</id>
    <content type="html"><![CDATA[
      <p>I have been working on migrating a website I did for a friend a while ago from an old ASP.NET application I built to my WordPress Amazon EC2 Instance over the last few weekends as the old server we were using for hosting is being retired. I have been working on a temporary domain whilst getting the site up and running using the subdomain dev.cafeontherye.co.uk and now it is time to migrate to www.cafeontherye.co.uk so I thought I would put the steps up here to update Wordpress Multisite change Domain name.</p>
<p>First step was to update the DNS settings and change the IP of www to point to the IP address of my WordPress instance on Amazon EC2. Whilst waiting for this to propagate I needed to update all of the settings in WordPress to point to the new domain. I use the <a href="http://wordpress.org/extend/plugins/wordpress-mu-domain-mapping/" title="WordPress Multisite Domain Mapping">WordPress MU Domain Mapping plugin</a> for this so navigated to my Network Admin &gt; Settings &gt; Domains and added a new entry to point to www and made it the primary for that domain. I then logged into MySQL workbench and ran the following.</p>
<pre><code class="language-sql">update [dbname].[wp_site_id]_options
   set option_value = replace(option_value, '[oldsiteurl]','[newsiteurl]');

update [dbname].[wp_site_id]_posts
   set post_content = replace(post_content, '[oldsiteurl]','[newsiteurl]');

update [dbname].[wp_site_id]_posts
   set guid = replace(guid, '[oldsiteurl]','[newsiteurl]');

update [dbname].[wp_site_id]_postmeta
   set meta_value = replace(meta_value, '[oldsiteurl]','[newsiteurl]');
</code></pre>
<p>Waited around four hours for everything to propagate and <a href="http://www.cafeontherye.co.uk/" title="Cafe On The Rye">Cafe On The Rye</a> lives again in it's new responsive WordPress form.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Metro Responsive Website Launch now with added Swipe</title>
    <link href="https://blog.david-jensen.com/metro-responsive-swipe-website-launch/"/>
    <updated>2012-11-18T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/metro-responsive-swipe-website-launch/</id>
    <content type="html"><![CDATA[
      <p>Over the past 12 months I have been working with an amazing team of people at Metro the largest free daily newspaper in the world to migrate their existing bespoke CMS and move them to WordPress with hosting provided by <a href="http://vip.wordpress.com/" title="WordPress VIP">WordPress VIP</a>. The press were invited in this week and the management team started to give them a flavour of what is to come in early December. I thought it would be nice to get some quotes out of these articles and put them here so I can remember the calm before the Metro responsive storm.</p>
<p>UPDATE: Swipe was removed from metro.co.uk in October 2013 due to these <a href="http://metro.co.uk/2013/10/01/why-swipe-has-been-removed-from-metro-co-uk-and-what-the-future-holds-4110488/" title="Why Metro removed swipe">reasons</a>.</p>
<blockquote>
<p>The Metro.co.uk site will become the first UK newspaper destination to allow mobile and tablet users to swipe between articles when it launches</p>
</blockquote>
<p><a href="http://www.marketingweek.co.uk/news/metro-ramps-up-mobile-drive/4004780.article" title="Metro Ramps up Mobile Drive">Metro Ramps up Mobile Drive, Marketing Week</a></p>
<blockquote>
<p>Linda Grant, the managing director at Metro, said the newspaper was the &quot;original mobile product&quot; when it launched targeting London Underground commuters in 1999.</p>
</blockquote>
<p><a href="http://www.guardian.co.uk/media/2012/nov/14/metro-website-android-kindle" title="Metro Mobile Launch">Metro to launch new website, Android app and Kindle Fire edition, The Guardian</a></p>
<blockquote>
<p>&quot;We've taken app functionality and applied to browser product,&quot; - Jamie Walters, Product Development Director, Metro</p>
</blockquote>
<p><a href="http://www.journalism.co.uk/news/metro-announces-mobile-first-strategy-and-responsive-site/s2/a551190/" title="Metro Mobile First Responsive">Metro Announces Mobile First Strategy and Responsive Site, Journalism.co.uk</a></p>
<blockquote>
<p>“We looked at Drupal and other platforms, but WordPress met our needs,” said Walters. “We no longer have to maintain back end systems.”</p>
</blockquote>
<p><a href="http://www.techweekeurope.co.uk/news/metro-newspapers-wordpress-open-source-99354" title="Metro WordPress">Metro Newspapers To Address “Smart Boredom” With Swiping, Techweek Europe</a></p>
<blockquote>
<p>Free urban newspaper brand Metro revealed this week it is experimenting with new ad formats such as mobile payments and full-page interstitials between swipes on its new website as it looks to boost the utility of the ads it presents its readers.</p>
</blockquote>
<p><a href="http://www.marketingweek.co.uk/opinion/newspapers-finally-living-up-to-digital-first-aspirations/4004804.article" title="Newspapers living up to Digital First">Newspapers finally living up to digital first aspirations, Marketing Week</a></p>
<p>UPDATE 24.02.2013: The Metro responsive WordPress project was launched on time and under budget and here are <a href="/planning-for-success-agile-collide/" title="Planning for success">more details</a> about how we approached this from a project management point of view. This was also be the first national UK Newspaper with a responsive site and the first for the swipe interaction across all devices that support it.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Backup WordPress to Dropbox on Amazon EC2 Centos Instance</title>
    <link href="https://blog.david-jensen.com/backup-wordpress-to-dropbox-amazon-ec2-centos/"/>
    <updated>2012-11-10T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/backup-wordpress-to-dropbox-amazon-ec2-centos/</id>
    <content type="html"><![CDATA[
      <p>I have been running multisite WordPress on my Amazon EC2 instance for almost a year and now that I have four sites running concurrently it is time to sort out a proper backup routine. Having had a look at all of the options and plugins it seemed like a good idea to backup WordPress to Dropbox and because of the size of my instance wouldn't cost anything. I also wanted full control via Linux rather than installing a plugin which I didn't trust. Also a good chance to do some more learning. Figured it would be a good idea to put the steps here so someone else can create should they want to do the same. I decided to run Dropbox under the ec2user as that is how everything else on my server is <a href="/install-wordpress-amazon-aws-ec2-linux-ebs/" title="Install WordPress on Amazon EC2">setup</a>.</p>
<h2>Backup Wordpress to Dropbox</h2>
<h2>Install Dropbox</h2>
<p>Download the latest stable <a href="https://www.dropbox.com/install?os=lnx" title="Linux Dropbox Install">Dropbox</a>.</p>
<p>32bit</p>
<pre><code class="language-bash">cd ~ &amp;&amp; wget -O - &quot;https://www.dropbox.com/download?plat=lnx.x86&quot; | tar xzf -
</code></pre>
<p>64bit</p>
<pre><code class="language-bash">cd ~ &amp;&amp; wget -O - &quot;https://www.dropbox.com/download?plat=lnx.x86_64&quot; | tar xzf -
</code></pre>
<p>Lets start Dropbox</p>
<pre><code class="language-bash">~/.dropbox-dist/dropboxd
</code></pre>
<p>You should get a message saying your account isn't syncing and to visit a URL. Copy the URL to a browser and login. Wait for the welcome message and then use Ctrl-C to exit. Now lets ensure that Dropbox will start when we restart our instance. Create a startup script.</p>
<pre><code class="language-bash">sudo vim /etc/init.d/dropbox
</code></pre>
<p>If you are using a stock Amazon Centos OS then copy the below. If not check for a script at the bottom of this <a href="http://www.dropboxwiki.com/Text_Based_Linux_Install" title="Install Dropbox Linux">page</a>.</p>
<pre><code class="language-bash"># chkconfig: 345 85 15
# description: Startup script for dropbox daemon
#
# processname: dropboxd
# pidfile: /var/run/dropbox.pid
# config: /etc/sysconfig/dropbox
#

### BEGIN INIT INFO
# Provides: dropboxd
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $syslog
# Should-Start: $syslog
# Should-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start up the Dropbox file syncing daemon
# Description: Dropbox is a filesyncing sevice provided by dropbox.com
# This service starts up the dropbox daemon.
## END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

# To configure, add line with DROPBOX_USERS=&quot;user1 user2&quot; to /etc/sysconfig/dropbox
# Probably should use a dropbox group in /etc/groups instead.

[ -f /etc/sysconfig/dropbox ] &amp;&amp; . /etc/sysconfig/dropbox
prog=dropboxd
lockfile=${LOCKFILE-/var/lock/subsys/$prog}
config=${CONFIG-/etc/sysconfig/dropbox}
RETVAL=0

start() {
   echo -n $&quot;Starting $prog&quot;
   if [ -z $DROPBOX_USERS ] ; then
      echo -n &quot;: unconfigured: $config&quot;
      echo_failure
      echo
      rm -f ${lockfile} ${pidfile}
      RETURN=6
      return $RETVAL
   fi
   for dbuser in $DROPBOX_USERS; do
      daemon --user $dbuser /bin/sh -c &quot;~$dbuser/.dropbox-dist/dropboxd&amp;&quot;
   done
   RETVAL=$?
   echo
   [ $RETVAL = 0 ] &amp;&amp; touch ${lockfile}
   return $RETVAL
}

status() {
   for dbuser in $DROPBOX_USERS; do
      dbpid=`pgrep -u $dbuser dropbox | grep -v grep`
      if [ -z $dbpid ] ; then
         echo &quot;dropboxd for USER $dbuser: not running.&quot;
      else
         echo &quot;dropboxd for USER $dbuser: running (pid $dbpid)&quot;
      fi
      done
}

stop() {
   echo -n $&quot;Stopping $prog&quot;
   for dbuser in $DROPBOX_USERS; do
      killproc ~$dbuser/.dropbox-dist/dropbox
   done
   RETVAL=$?
   echo
   [ $RETVAL = 0 ] &amp;&amp; rm -f ${lockfile} ${pidfile}
}

# See how we were called.
case &quot;$1&quot; in
   start)
      start
      ;;
   status)
      status
      ;;
   stop)
      stop
      ;;
   restart)
      stop
      start
      ;;
   *)
      echo $&quot;Usage: $prog {start|status|stop|restart}&quot;
      RETVAL=3

esac

exit $RETVAL
</code></pre>
<p>Now we need to add a file which contains the ec2-users that we want to run the service.</p>
<pre><code class="language-bash">sudo vim /etc/sysconfig/dropbox
</code></pre>
<p>Add the following line to the file and save (:wq!)</p>
<pre><code>DROPBOX_USERS=&quot;ec2-user&quot;
</code></pre>
<p>Now we need to sort the file permissions.</p>
<pre><code class="language-bash">sudo /bin/chmod 0755 /etc/init.d/dropbox
sudo /bin/chmod 0644 /etc/sysconfig/dropbox
sudo /bin/ls -l /etc/init.d/dropbox /etc/sysconfig/dropbox
</code></pre>
<p>Turn it on</p>
<pre><code class="language-bash">sudo chkconfig dropbox on
</code></pre>
<p>Check that it worked, look for Dropbox in the list.</p>
<pre><code class="language-bash">sudo chkconfig --list | egrep '3:on|5:on' | less
</code></pre>
<p>Start the service</p>
<pre><code class="language-bash">sudo service dropbox start
</code></pre>
<p>Hopefully everything should now be working fine.</p>
<h2>Move Dropbox Folder</h2>
<p>I moved my Dropbox folder to my EBS volume so it would persist, then symbiotically linked it back to the home directory.</p>
<pre><code class="language-bash">sudo service dropbox stop
sudo mv ~/Dropbox /vol/Dropbox
sudo ln -s /vol/Dropbox ~/
sudo service dropbox start
</code></pre>
<p>Now it is time to tidy up the directories where Dropbox sit and ensure that only the folders you want synced are turned on.</p>
<h2>Turn On Dropbox Selective Sync</h2>
<p>Go to your home directory</p>
<pre><code class="language-bash">cd ~
</code></pre>
<p>We now need to download the Python Script which is used to manage Dropbox from the Command Line and give it the right permissions.</p>
<pre><code class="language-bash">wget -O ~/dropbox.py &quot;http://www.dropbox.com/download?dl=packages/dropbox.py&quot;
chmod 755 ~/dropbox.py
</code></pre>
<p>Now lets check Dropboxes status</p>
<pre><code class="language-bash">./dropbox.py status
</code></pre>
<p>Hopefully should now be syncing up, most likely you won't want everything to sync so you can use the 'exclude add' command to stop folders you don't need. Run the below and it will show your synced folders.</p>
<pre><code class="language-bash">cd Dropbox
~/dropbox.py ls
</code></pre>
<p>You can stop each of them syncing by using the following command.</p>
<pre><code class="language-bash">~/dropbox.py exclude add ~/Dropbox/Public
~/dropbox.py exclude add ~/Dropbox/'Camera Uploads'
</code></pre>
<p>If you run the below again you can see that they are dropping off.</p>
<pre><code class="language-bash">~/dropbox.py ls
</code></pre>
<p>Also worth turning off LAN sync as you won't need it.</p>
<pre><code class="language-bash">~/dropbox.py lansync n
</code></pre>
<h2>Backup WordPress to Dropbox Including Database and Content</h2>
<p>Create a folder for backups.</p>
<pre><code class="language-bash">mkdir /vol/Dropbox/Backup
</code></pre>
<p>Now we want to write a quick script to copy the files from html/wp-content to Dropbox/Backup/wp-content and dump the MySQL. Create the below file, it should be synced to your other computers as soon as you save.</p>
<pre><code class="language-bash">vim /vol/Dropbox/Backup/backup.sh
</code></pre>
<p>Here is the script, change the paths /vol/html/ to where you have your wp-content folder and /vol/Dropbox/Backup to where your Dropbox sits, plus update your MySQL password.</p>
<pre><code class="language-bash">#!/bin/sh

echo &quot;Backup Start&quot;

echo &quot;Syncing wp-content Files from html to Dropbox&quot;

sudo rsync -vaz --delete --update /vol/html/wp-content/ /vol/Dropbox/Backup/wp-content/

echo &quot;Backing up database&quot;

mysqldump -uroot '-p[password]' --single-transaction --routines --triggers --all-databases &gt; /vol/Dropbox/Backup/backup_db.sql

echo &quot;Backup Finish&quot;
</code></pre>
<p>Now lets run it to see if it works. (Update: previously I had used cp to copy all the files across every night. However I just noticed that it melts my server doing the update so have just updated to use rsync and just copy the files that have changed. Showing my Linux rookie credentials.)</p>
<pre><code class="language-bash">sudo chmod u+x /vol/Dropbox/Backup/backup.sh
sudo /vol/Dropbox/Backup/backup.sh
</code></pre>
<p>Now we have our script sorted we need to create a cron job to run it once a day at 1am. You will need to stop cron.</p>
<pre><code class="language-bash">sudo service crond stop
</code></pre>
<p>Now lets edit the file which runs our jobs.</p>
<pre><code class="language-bash">vim /etc/crontab
</code></pre>
<p>Insert the below line, below this one <code># * * * * * user-name command to be executed</code>:</p>
<pre><code>0 1 * * * root ./vol/Dropbox/Backup/backup.sh
</code></pre>
<p>Save and start cron backup.</p>
<pre><code class="language-bash">sudo service crond start
</code></pre>
<p>You can now rest easily that every night at 1am you can backup wordpress to dropbox including the entire wp-content folder plus a database dump. Perfect for the small time blog runner. Props to the following sites that were a big help in this process.</p>
<ul>
<li><a href="http://buildcontext.com/blog/2012/dropbox-linux-ubuntu-ec2-linode-selective-sync" title="Selective Sync Linux Dropbox">Dropbox, Selective Sync</a></li>
<li><a href="http://kiteplans.info/2012/03/26/centos-virtualmin-server-backups-dropbox/" title="Centos Dropbox Install">Centos Dropbox Install</a></li>
<li><a href="http://www.dropboxwiki.com/Text_Based_Linux_Install" title="Dropbox Text Based Install">Dropbox Wiki Text Based Linux Install</a></li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>WordPress Apache Permissions For Easy Update</title>
    <link href="https://blog.david-jensen.com/wordpress-apache-permissions-easy-update/"/>
    <updated>2012-10-28T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/wordpress-apache-permissions-easy-update/</id>
    <content type="html"><![CDATA[
      <p>I need to update my WordPress Apache permissions and I have them set so WordPress doesn't have write access to the main HTML folder. I always have to Google to remember what I need to set so figured I would write it here so I wouldn't forget.</p>
<pre><code class="language-bash">sudo find /vol/html/ -type d -exec chmod 777 {} \;
sudo find /vol/html/ -type f -exec chmod 777 {} \;
</code></pre>
<p>Once these have run you can run the update successfully, you then just put the files back to my what my <a href="/wordpress-amazon-ec2-apache-permissions-wordpress/" title="WordPress EC2 Apache Permissions">previous post</a> recommended.</p>
<pre><code class="language-bash">sudo find /vol/html/ -type d -exec chmod 755 {} \;
sudo find /vol/html/ -type f -exec chmod 644 {} \;
sudo chmod -R 775 /vol/html/wp-content;
</code></pre>
<p>Happy updating, though if it doubt you can't beat the <a href="http://codex.wordpress.org/Hardening_WordPress" title="Hardening WordPress">Hardening WordPress</a> page on the Codex.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>LeWeb London 2012 - Lessons and Learnings</title>
    <link href="https://blog.david-jensen.com/leweb-london-2012-lessons-learnings/"/>
    <updated>2012-06-30T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/leweb-london-2012-lessons-learnings/</id>
    <content type="html"><![CDATA[
      <p>I was very fortunate to spend two days at <a href="http://london.leweb.co/" title="LeWeb London 2012">LeWeb London</a> <a href="http://london.leweb.co/" title="LeWeb London 2012">2012</a> on the 19th &amp; 20th June this year. Methodist Central Hall in Westminster was a fitting venue for what turned out to be an informative debate on the state of the European start up scene. It provided me with some really good insight into what it takes to build and maintain a successful business. There was a certain amount of fluff and pomp from both startups, investors and successful entrepreneurs so I thought it would be nice to cut through that alongside my highlights and learnings below.</p>
<p><img src="/assets/images/leweb-london-2012-lessons-learnings/LeWeb-Stage.jpg" alt="LeWeb London 2012 Stage"></p>
<h2>LeWeb London 2012 - Highlights and Key Takeaways</h2>
<h2>Day One</h2>
<h2>Jamie Oliver,  Television Personality &amp; Kevin Systrom, Co-Founder &amp; CEO, Instagram with Loic Le Meur, LeWeb  London 2012 Founder</h2>
<p>I have to admit I am quite a fan of how Kevin Systrom has <a href="http://www.forbes.com/sites/limyunghui/2012/04/09/inspiring-insights-by-instagram-ceo-kevin-systrom-the-man-who-built-a-1-billion-startup/" title="Building Instagram">approached building Instagram</a> and in the first big talk he was alongside Jamie Oliver.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Pdbzmk0xBW8" frameborder="0" allowfullscreen=""></iframe>
<h2><strong>Key Takeaways:</strong></h2>
<ul>
<li>Photo's bridge gaps that languages can't</li>
<li>People tend to be much nicer when using images than when using words</li>
<li>Instagram has democratised the creative process</li>
<li>Photo's on Instagram tend to have around a 10 hour interest window</li>
<li>Instagram now has 50 million+ users</li>
<li>Instagram solved the problem of how people communicate visually using mobile</li>
<li>Instagram API has allowed them to keep their focus on mobile and let other people fill out their ecosystem</li>
<li>Instagram are working on the ability to allow you to go back in time to revisit older photos</li>
</ul>
<blockquote>
<h4>“It’s like an empty stage with a drum kit and guitars–businesses need to hire passionate musicians to use them.”</h4>
</blockquote>
<p><strong>Jamie Oliver</strong> on social media</p>
<h2>Phil Libin, CEO, Evernote &amp; Loic Le Meur, Founder, LeWeb London 2012</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/1Y0_lC5tZGI" frameborder="0" allowfullscreen=""></iframe>
<h2>Key Takeaways:</h2>
<ul>
<li>Evernote has 34 million users</li>
<li>They make money from happy people and currently 4% of people pay</li>
<li>The longer someone is a user the more likely they are to pay which rises to a maximum of 25%</li>
<li><a href="http://t.co/UigkjlYA" title="Evernote Payment Details">Average $US per user per platform</a>
<ul>
<li>$1.06 - Android</li>
<li>$1.44 - Windows Phone 7</li>
<li>$1.79 - iPhone</li>
<li>$2.01 - Blackberry</li>
<li>$2.18 - iPad</li>
</ul>
</li>
<li>50% of Evernote's development time is spent on Apple 50% on all other platforms</li>
<li>Evernote Food makes $6.73 a user due to its niche user base</li>
<li>The 30% they pay to Apple is a bargain when you include the marketing you get from being in the App Store</li>
<li>More than happy for users to use in app purchases as it reduces the friction of their payment process</li>
</ul>
<blockquote>
<h4>&quot;Spend every single minute building the best product, if Google or anyone else manages to build a better product then they deserve to win and the world will be a better place for it.&quot;</h4>
</blockquote>
<p><strong>Phil Libin</strong> on competition</p>
<h2>Jason Goldberg, Founder &amp; CEO &amp; Bradford Shane Shellhammer, Co-Founder &amp; Chief Creative Officer, Fab &amp; Michael Arrington, General Partner, CrunchFund</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Gsj-a9v7IIE" frameborder="0" allowfullscreen=""></iframe>
<h2><strong>Key Takeaways:</strong></h2>
<ul>
<li>Jason Goldberg lost $47 Million dollars in his previous start-up</li>
<li>Focus on being the best at one thing</li>
<li>When they pivoted from a Gay Social site to an eCommerce platform they turned their old site off for three months to ensure they could focus on getting the new one right</li>
<li>Build the product first then the company will follow</li>
<li>Experiment to get the product right then iterate to improve specifics</li>
<li>50% of their members come from social sharing</li>
<li>Friction is the most common problem for people to pay for things online</li>
</ul>
<blockquote>
<h4><strong>“It’s all about shifting from impressions to connections”</strong></h4>
</blockquote>
<p><strong>Bonin Bough</strong> from Kraft on the future of online advertising</p>
<h2>Martin Varsavsky, Founder &amp; CEO, Fon</h2>
<p>Amazing talk on how Martin achieves the focus and lifestyle that he needs to run a very successful company at scale.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/GB10ilqE6sw" frameborder="0" allowfullscreen=""></iframe>
<blockquote>
<h4>&quot;Delegation means that things will never be done the way you want but it is the only way to buy you time to do the things you love.&quot;</h4>
</blockquote>
<p><strong>Martin Varsavsky</strong></p>
<p><img src="/assets/images/leweb-london-2012-lessons-learnings/Conference-Hall.jpg" alt="Methodist Central Hall Westminster venue for LeWeb London 2012"></p>
<h2>Day Two</h2>
<h2>Riccardo Zacconi, Co-Founder &amp; CEO, King.com &amp; Eric Eldon, Co-Editor, TechCrunch</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Kpz9vpBoSKE" frameborder="0" allowfullscreen=""></iframe>
<h2>Key Takeaways:</h2>
<ul>
<li>King.com has 12 million daily users, 50 million monthly users but focus is on daily numbers</li>
<li>They launch 80 games a year on their website for testing and the ones that get traction are then added to Facebook around 10%</li>
<li>Monetise via advertising, virtual goods and VIPs</li>
<li>Casual games are the most popular</li>
<li>Cross platform capabilities really helps drive growth</li>
<li>Core demographics female over 25 with core players female over 35</li>
<li>Built a platform which enables them to wrap games with a social layer easily to help them scale</li>
</ul>
<h2>Shakil Khan, Head of Special Projects, Path &amp;Loic Le Meur, Founder, LeWeb London 2012</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/thH_DBqsmQk" frameborder="0" allowfullscreen=""></iframe>
<h2>Key Takeaway:</h2>
<ul>
<li>Facebook is copying Path on mobile!</li>
</ul>
<blockquote>
<h4>&quot;Facebook is building the cities, Path is building the homes.&quot;</h4>
</blockquote>
<p>Shakil Khan</p>
<h2>Sam Shank, Co-Founder &amp; CEO, HotelTonight &amp; MG Siegler, General Partner, CrunchFund</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/dxxRe_d1inE" frameborder="0" allowfullscreen=""></iframe>
<h2>Key Takeaways:</h2>
<ul>
<li>Same day booking system, 100% focus on mobile</li>
<li>Some hotels still require a fax for booking</li>
<li>8 seconds to pay, 3 taps and a swipe, was just 3 taps but was too easy to book accidentally</li>
<li>No legacy and a very singular focus on mobile and same day booking allows them to differentiate</li>
</ul>
<blockquote>
<h4>&quot;Lack of focus is the biggest killer for startups. I named my company HotelTonight to enforce this.&quot;</h4>
</blockquote>
<p>Sam Shank</p>
<h2>Baratunde Thurston, Comedian</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/li0AjbJca00" frameborder="0" allowfullscreen=""></iframe>
<h2>Key Takeaways:</h2>
<ul>
<li>He is a funny dude!</li>
<li>The Onion vote on best headlines for major stories out of a list compiled by staff</li>
</ul>
<h2>Dr. DJ Patil, Data Scientist in Residence, &amp; Josh Elman, Principal, Greylock Partners</h2>
<p>This was one of my favourite talks and they both did an amazing job of showing how big data works and can help shape decisions and the specific example from Twitter from 13 minutes in is priceless.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/L2snRPbhsF0" frameborder="0" allowfullscreen=""></iframe>
<blockquote>
<h4>&quot;Data science is the new black.&quot;</h4>
</blockquote>
<p>Tim O'Reilly</p>
<h2>Key Takeaways:</h2>
<ul>
<li>Use data to have a conversation</li>
<li>Use data to find inflection points and then optimise towards</li>
</ul>
<h2><strong>Data Scientific Method</strong></h2>
<ul>
<li>Start with a question</li>
<li>Leverage all your current data</li>
<li>Create features and run tests</li>
<li>Analyse and draw insights</li>
<li>Let data frame the next conversation</li>
</ul>
<h2>Conclusions</h2>
<p>So there was <a href="http://leweb.co/blog/list-all-videos-le-web-london-2012" title="LeWeb'12 London List of all videos">a lot to take in</a> at LeWeb London 2012 and congratulations to <a href="http://www.blippar.com/" title="Blippar">Blippar</a> for winning the startup competition. Had an interesting meeting with <a href="http://teleportd.com/" title="Teleportd">Teleportd</a> who came third about how we might be able to use their social photo aggregation tool at Metro.</p>
<h2>LeWeb London 2012 - My Learnings</h2>
<p>It wasn't until a couple of days later when I sat down to compile this post that I really began to distil how to apply startup thinking to a more established company. However can any large company these days really afford not to think like a startup? The world is changing around us at such a pace and modern technology aids rapid disruption of just about anything, so no one should get complacent. Most of the questions that the startup competition judges asked, were around what problem were these startups trying to solve. The more concrete the answer the easier it was to see how effective each of these businesses were. The other really useful part of having a clear problem to solve was the focus that it provided in asking the right questions around how the product was being developed. Focus was a reoccurring theme throughout from both entrepreneurs and seasoned executives. The CEO of HotelTonight even went as far as naming his current venture to ensure that they weren't distracted from providing the best experience when you are in need of a Hotel Tonight.   When Fab pivoted rather than trying to keep their existing community happy they turned the site off whilst redeveloping to ensure that they weren't distracted at all. I can't imagine that these decisions were easy or to some people seemed very logical but are very <a href="http://www.lean.org/whatslean/" title="What is lean?">Lean</a> in their approach. The clear goals and focus also make it much easier to use data in a way to shape decision making. By having a clear focus on growing users Twitter was able to work out the tipping points to turn first time users into regulars. This enhanced their focus on optimising those parts of the user journey that provided these metrics until they reached hyper growth. User experience was another key theme throughout LeWeb London 2012, with so much choice available to end users if your product doesn't delight them on a regular basis then they aren't likely to stick around. This can be hard from a scientific standpoint to measure and optimise but focusing on keeping people happy has allowed Evernote and many others to grow very sustainable profits. Path's lazer focus on this area has also allowed them to differentiate from Facebook on mobile to the point that they are now copying them. There is always someone bigger out there but most likely they will have a much larger set of people to keep happy and that can end up detracting from the end product. You have to be constantly looking forwards and focused on improving rather than looking at other people. Copy cat startups got a pretty bad rap from stage participants and especially from investors. By doing something different and disrupting existing businesses your potential rewards are so much greater than being just another clone. LeWeb London 2012 encapsulated an amazingly diverse set of ideas and thoughts into a rather enjoyable set of talks that didn't really speak to the &quot;Faster than realtime&quot; theme but not sure that was the point. London as a startup scene definitely isn't the Valley but that is probably why it is interesting to many.</p>
<h2>Key Takeaways:</h2>
<ul>
<li>Solve a problem</li>
<li>Ask the right questions</li>
<li>Focus on the above to at all costs</li>
<li>User Experience is a key differentiator</li>
<li>Use data to drive conversations and frame decisions</li>
<li>Happy users stick around longer and spend more money</li>
</ul>
<p><img src="/assets/images/leweb-london-2012-lessons-learnings/LeWeb-Metro.jpg" alt="Metro Logo in Blippar Presentation at LeWeb London 2012"></p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Build, measure, learn, iterate my vision for an agile future.</title>
    <link href="https://blog.david-jensen.com/build-measure-learn-iterate-vision-agile-future/"/>
    <updated>2012-06-19T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/build-measure-learn-iterate-vision-agile-future/</id>
    <content type="html"><![CDATA[
      <p>Recently I have been going through a process of looking 18 months into the future and as part of that have written a story of to illustrate where we are going and how I am going to help them get there. I thought it would make sense to publish this almost as a time capsule here to see how far I can get in my ambitious plans.</p>
<h2>My Story to Come</h2>
<p>This story begins three years ago when I first joined Metro to create a development team. Prior to this all development had been done by a central group resource, they took at least 6 months to get anything done and when it was finally delivered, it wasn’t what you asked for in the first place. The lack of agility was seriously harming Metro’s ability to make the most of product, commercial and editorial opportunities that were presented to them. It took the next 18 months to change not just the way that development was run, but also the way that Metro thought about development and the processes that guide it. Our first goal was to become Agile which is a word that is bandied about a lot but essentially means working in smaller iterations using small self-organising teams and regularly reviewing what and how we are working to continuously improve.</p>
<p>This path was not without its road bumps and the first major one was the development of the TV Product, this was an extremely complicated system which allowed people to write reviews of 15,000 TV shows. It took over six months of development and generated less than 100 reviews. As part of our Agile process we sat down at the end at realised we had to change even further. We needed to understand the drivers of ours users behaviour and ensure that we understood them before we over engineered a system which didn’t do what they needed. This is when we started to look at the Lean Methodology of manufacturing promoted by Toyota since the 1990’s and more recently by Eric Reis in his book The Lean Start-up. Being lean means that you limit the number of things that you are working on and look at each iteration more scientifically. For each iteration you have a customer based hypothesis that you build as quickly as possible before releasing and measuring its impact against your hypothesis, you then make your next decision based on the feedback.</p>
<p>Build, measure, learn, iterate became the development team’s mantra and ensured that we only built what was required and we learn't from every iteration. This ensured waste was kept to a minimum and constant feedback was able to help shape future developments. This enabled Metro to embrace the constant change that is present in our environment and use it as a competitive advantage. It didn’t take away the need for an end goal just ensured that the journey we took was as effective as it could be every step of the way. This quote I think sums it up nicely. “It is not the strongest of the species that survives, nor the most intelligent, it is the one that is the most adaptable to change”. It wasn’t just Metro who had used these principles Facebook have the words “Done is better than perfect” on their walls and both Facebook and Apple work in small teams specifically focused delighting their customers.</p>
<p>18 months ago Metro decided that they needed to take some brave decisions to diversify their business away from print revenues. With all of the learning that development team and Metro had been through over the previous 18 months and with each of the new start-up businesses having a technology component I decided it was time to break these agile and lean practices out of the development team and get them in use in the wider business. I realised that the best way to do this was to get involved with each of these new ideas and ensure that the both development and business resources used our template of build, measure, learn, iterate.</p>
<p>Boiling all of our new ideas down to a simple test and using data to shape our decision making process has been instrumental in changing the face of Metro to the one that you see today. We now always test our assumptions and if they are not correct, we fail early and quickly adapt. All data and experiments are shared through the use of highly visible dashboards. This has allowed Metro to collectively learn from each other and this level of transparency and openness has accelerated Metro’s decision making process and enabled it to stay far ahead of their competition. I would like to finish with a quote from Winston Churchill “Now this is not the end. It is not even the beginning of the end. But it is perhaps, the end of the beginning.”</p>
<p>Books that helped me shape this vision.</p>
<p><a href="http://www.amazon.co.uk/Leaders-Guide-Radical-Management-Reinventing/dp/0470548681" title="Radical Management">Radical Management</a> by <a href="https://twitter.com/#!/stevedenning" title="Steve Denning">Steve Denning</a> <a href="http://www.amazon.co.uk/The-Lean-Startup-Innovation-Successful/dp/0670921602/" title="The Lean Startup">The Lean Startup</a> by <a href="http://www.startuplessonslearned.com/" title="Eric Ries">Eric Ries</a></p>

    ]]></content>
  </entry>
  
  <entry>
    <title>WordPress Categories vs Tags</title>
    <link href="https://blog.david-jensen.com/wordpress-categories-vs-tags/"/>
    <updated>2012-04-15T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/wordpress-categories-vs-tags/</id>
    <content type="html"><![CDATA[
      <p>Categories vs Tags is one of the biggest decisions around how you setup a good taxonomy using WordPress. Utilising both categories and tags can make your site easier to navigate which will help both people and search engines. It has taken me a while to get my head around this so thought I would run through my thoughts in the hope that it might help shape your decision making.</p>
<p>Categories in my opinion are best used for the main structure of your site and can be thought about a bit like a menu. Each post should only be present in one category. Categories can also have  sub categories, this can be handy to split your content down into more specific areas when you have enough posts. A good example of this would be sport, for example for on a news based site you are quite like to have sport as a top level category, then under that individual sports such as football and cricket.</p>
<p>Tags in my opinion are best used to cut across categories and a post should have many tags but only one category. Tags have the advantage of being able to be combined to bring back more specific data when required. I think a good example of this would be a tag for &quot;David Beckham&quot;, as he is both a footballer and a celebrity he could appear under either a sport or celebrity category and if you wanted to get more specific you could search for both &quot;David Beckham&quot; + &quot;Victoria Beckham&quot; if you are interested in their goings on or &quot;David Beckham&quot; + &quot;LA Galaxy&quot; if you wanted to know about his latest sport endeavours.</p>
<p>Ensuring that your taxonomy is clean and consistent can really help both people and robots navigate your site. Starting out in the right way with the right structure will lead to better results for everyone as changing later can be quite detrimental to any search juice that you have built up especially if you have the category name in your URL.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>An Agile Process Should Be Shaped To Fit Your Environment</title>
    <link href="https://blog.david-jensen.com/agile-process-shape-environment/"/>
    <updated>2012-04-06T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/agile-process-shape-environment/</id>
    <content type="html"><![CDATA[
      <p>We have been recruiting a Business Analyst for a big project that we have coming up at work. They have all been interested in how our current process works. It has got me thinking why our process is the way that it is and my conclusion is the main reason is that it has been shaped in a true agile fashion to fit the environment that we operate in.</p>
<p>It is easy to get some experts in, go on a course or read how SCRUM should be done and implement it exactly as they have described. I have however found that the most important part of the Agile process is the retrospective and subsequent changes to your process. This self learning and feedback needs to happen not just within the development team but also with the business environment that they operate in.</p>
<p>A lot of processes assume certain resource requirements and business buy-in. However this is rarely the case when you start out. There are a lot of companies that say they do agile but aren't really agile more like Waterfall using SCRUM. Another major part of Agile is self organisation so someone managing the process too tightly stops this happening. Though at the beginning it is obviously good to start from a template and iterate from that.</p>
<p>It has taken me over 18 months to get both my team and the business in a place that they don't just get Agile but they are Agile in their approach. Quite a bit of this was born out of making mistakes along the way and the specific learning that we were able to distill from those. We can still improve but that is part of the appeal to me.</p>
<p>Speed of adaptability is essential in the modern business world to stay competitive. It is also immensely rewarding to see a team come together and improve over time. Two weeks ago we released early for the first time in our history. I am sure it won't be the last.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>In Development the most obvious choice is quite often the best one</title>
    <link href="https://blog.david-jensen.com/development-most-obvious-choice-best-one/"/>
    <updated>2012-03-08T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/development-most-obvious-choice-best-one/</id>
    <content type="html"><![CDATA[
      <p>It started with a conversation regarding Node.js as one of my developers has been using it to write a RESTful API. We had spun up an Amazon EC2 server and RDS backend for the service, which is the beginnings of a content shaping algorithm. This rapid prototype has shown real promise and now we are looking at using it as the core to our Facebook Application Homepage. With this in mind I started to think about how this would work in a production environment. This is when I thought back to some recent experiences and quickly decided that Node.js as great as it is, really isn't the best option for the team or company at this point in time. Here are my reasons why:</p>
<h2>Support</h2>
<p>Only one developer has any idea of how Node.js works and when there is a problem as there will be one when you are using cloud based hosting. This could be slightly mitigated by having a Wiki. However usually it is out of office hours during weekend support when you find out the Wiki is not quite 100% up to date.</p>
<h2>Consistency / Learning Curve</h2>
<p>Teams change and as we move forward we need to ensure that our code is written and approached in a consistent way. This will ensure that if a developer wants to get involved with different projects they can easily jump between them. It also ensures that if the person who wrote the code isn't around supporting it is much easier. Yet another barrier to entry will also only reduce the ability to quickly up-size should the project or team need extra resources.</p>
<h2>Agility / Speed</h2>
<p>We are an Agile team and working in short iterations delighting our customers is what we do best. By being consistent we become more agile, it aids self forming teams and enables continuous learning. A common approach make it easier for the knowledge to be passed around which amplifies its effect. Working on similar projects allows my team to take those learnings and get faster at doing what they do. The libraries and helpers that are developed can be used in as many places as possible to reduce code duplication and increase testability.</p>
<h2>History</h2>
<p>My team inherited a custom written CMS solution that we have been supporting for the past 18 months. It was written using Apache Cocoon and GWT as a front end with an Adobe CRX NoSQL solution as the data store. Due to none of these technologies being widely known development was up to ten times slower than it should have been because of the learning curve and lack of consistency. We also chose to use MooTools as a JavaScript framework for our front end and this has restricted the interoperability of our site and it doesn't get along with jQuery which is what the rest of the web uses.</p>
<h2>Lack of a clear benefit</h2>
<p>Node.js is a great solution if you have requirements for massive concurrency. However that requirement for our current problem as it will be cached behind Akamai. In this case there is not enough of a business reason to do something different.</p>
<p>As you can see I thought long and hard about this and I hope my conclusions make sense. I am really glad that we now have the knowledge of how Node.js works and when a project comes us that does have a clear benefit I will reconsider. However until then we are going to go with the obvious choice and rewrite this API in Spring MVC to be slightly less bleeding edge.</p>
<p>UPDATE Dec 2013: Looking back on the above post I still think it was the right decision at the time but the flip argument to all of the above is that it would have been great to learn some new technology and get the team enthused about this. Small distinct projects are a great way of trying out new bits of technology. Sure there is a risk associated if it doesn't work out. However if you aren't trying new things then you will never know when something better comes along. If I had to make the same decision again I would probably go the other.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>HTC Titan Review (WP7)</title>
    <link href="https://blog.david-jensen.com/htc-titan-review-wp7/"/>
    <updated>2012-02-19T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/htc-titan-review-wp7/</id>
    <content type="html"><![CDATA[
      <p>As we were working on a Windows Phone 7 (WP7) application for work we had to buy some handsets for testing. I decided that I would give the HTC Titan a go as I was interested to see what it is like to use a phone with a 4.7&quot; screen. It was also my first time using WP7 as an OS with my primary device being a iPhone 4. I was very pleasantly surprised when I got the phone out of the box that it wasn't too heavy. Once I turned it on I was immediately drawn into the screen. The setup process for WP7 is very straight forward and I really enjoy the simplicity of live tiles. The fact that they can update and show interesting bits of information without being complicated to setup is a real bonus to WP7. I have spent a lot of time using Android recently and it always takes me a long time to get the widgets setup and the home screens working in a way that makes sense to me. There was none of this with WP7. The great thing about having a really strong design is that a lot of the apps use this as their template so if you enjoy the way that this works it is easy to pick up and you automatically know how to use them. I was also very impressed with the camera and software which seems to predict the best time to take the photo once you have the button pressed. Some really good results and always capturing the right shot was nice. I used SkyDrive to get the photos off the phone and into the cloud which is a nice touch. Zune software is similar to iTunes and a necessary evil, much better than the random software that ships with Android but still overblown for what it is really. My friend has a Zune pass and says that it works out really well, got enough music myself without needing to stream. This brings me to my major gripe with WP7 music playback, I listen to a lot of mixed music like the Fabric series, if you have ripped these as separate tracks then their is a skip in-between tracks. To me this is a golden sin and one of the reasons that I couldn't use this phone as my main device. The other main issue is the cost of Apps, due to the lack of numbers developers have to charge more. What would most likely be free on Android and £.99 on iPhone is upward of £3.99 on the WP7 marketplace. Makes it a lot harder to make those impulse purchases. A final issue is that currently there is no Skype at all on the WP7 marketplace or integrated on the phone. This is crazy considering Microsoft owns Skype and a major oversight. I know they are probably waiting to do a deep integration but with family around the world no access to Skype is a real oversight. Overall I really enjoyed using the HTC Titan for a couple of months and really think that WP7 Mango and the Metro interface should be a major competitor to Apple and Android if it can gain traction. Once Microsoft bakes Skype into it and allows you to stream to your Xbox as well as use it as a keyboard I think there will be more reasons to buy. HTC have done a good job to give people a reason to buy something different from the lovely Nokia sporting WP7 and the screen with live tiles is just amazing. Good battery life and easy input on a big screen is a winner. Not going to replace my iPhone 4 but I have been missing WP7 since we moved on to building an Android App. If you do get a HTC Titan or any Windows Phone 7 phone then you should download the Metro App for it <a href="http://www.windowsphone.com/en-GB/apps/665427b7-b091-468b-a18d-715df4215059" title="Metro Windows Phone 7 App">here</a> (shameless plug).</p>
<p><img src="/assets/images/htc-titan-review-wp7/HTC-Titan-Sim-Free.jpg" alt="HTC Titan"></p>
<p><strong>Specifications</strong></p>
<ul>
<li><strong>Software:</strong> Windows Phone 7.5 Mango</li>
<li><strong>Processor:</strong> 1.5GHz</li>
<li><strong>Memory slot:</strong> No</li>
<li><strong>Display:</strong> 4.7in 480 x 800 pixels multitouch</li>
<li><strong>Connectivity:</strong> GSM/GPRS/EDGE/HSDPA, Wi-Fi 802.11b/g/n, Bluetooth, A-GPS</li>
<li><strong>Ports:</strong> Micro USB, 3.5mm headphones</li>
<li><strong>Camera:</strong> 8 megapixel, F2.2 lens, dual LED flash, and BSI sensor</li>
<li><strong>Video playback:</strong> 3gp, .3g2, .mp4, .m4v, .mbr, .wmv</li>
<li><strong>Audio playback:</strong> m4a, .m4b, .mp3, .wma</li>
<li><strong>Radio:</strong> No</li>
<li><strong>Battery:</strong> Li-ion 1600 mAh</li>
<li><strong>Size:</strong> 132x71x10mm</li>
<li><strong>Weight:</strong> 119g</li>
</ul>

    ]]></content>
  </entry>
  
  <entry>
    <title>Thinking Lean to Combat Change</title>
    <link href="https://blog.david-jensen.com/thinking-lean-combat-change/"/>
    <updated>2012-02-02T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/thinking-lean-combat-change/</id>
    <content type="html"><![CDATA[
      <p>I have been working in software development for ten years and the one constant throughout my whole career is change. Change in technology, change in working practices and changing business requirements. During this period I have constantly battled against the best way to deal with change so it has the least impact on the day to day activities of myself and my team and to ensure that our output is an actual business requirement. The main way that we have achieved this is by becoming <a href="http://en.wikipedia.org/wiki/Lean_manufacturing" title="Lean Manufacturing">Lean</a> which is based on a method of manufacturing invented by Toyota in the 1990’s. We have shortened our iterations to less than two weeks and limited the number of things that can be worked on at any time. This means that we can get feedback from our customers as early as possible and build what they want and not what we think they want. <a href="http://www.startuplessonslearned.com/" title="Eric Ries">Eric Ries</a> has taken this methodology and applied it to starting a business, whether that business is new or part of a larger organisation. This approach which is customer centric focuses on building what the customer wants in as short a time as possible and then releasing it to learn from how customers actually use it. It is a big change from the build it and they will come large product based development approach and takes a while to get right. However if each time you release something it is to test a theory and you get feedback that you can use to shape your future strategy and vision. It requires a direction but not a detailed project plan but multiple iterations or ability to change tact should reality not meet your expectations.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>WordPress Edit Image Not Working on Amazon EC2</title>
    <link href="https://blog.david-jensen.com/wordpress-edit-image-functionality-not-working-on-amazon-ec2/"/>
    <updated>2012-01-14T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/wordpress-edit-image-functionality-not-working-on-amazon-ec2/</id>
    <content type="html"><![CDATA[
      <p>I had an issue with my WordPress edit image not working when I installed it myself on Centos. If you would like the ability to do advanced image editing in WordPress when running on Amazon EC2 Linux you will need to make sure that you have installed the <a href="http://php.net/manual/en/book.image.php" title="PHP GD reference">PHP GD</a> libraries or none of the image editing capabilities will show up.</p>
<pre><code class="language-bash">sudo yum install php-gd
</code></pre>
<p>After a lot of searching I found this <a href="http://stackoverflow.com/a/6117530/1136104" title="WordPress Answer">great answer</a> on Stack Overflow which pointed me in the right direction. Have added this step to my previous post for setting up WordPress as well.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Amazon EC2 Apache Setup Permissions for WordPress</title>
    <link href="https://blog.david-jensen.com/wordpress-amazon-ec2-apache-permissions-wordpress/"/>
    <updated>2012-01-06T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/wordpress-amazon-ec2-apache-permissions-wordpress/</id>
    <content type="html"><![CDATA[
      <p>I have been doing my best to figure out the Amazon EC2 Apache setup of permissions to enable WordPress to be able to manage all of the files on my Amazon EC2 instance without WordPress asking for FTP permissions when I try to upload a plugin or theme via the Admin site. I ended up having to give file and group ownership of the files in my html folder to apache user for WordPress to run correctly. This <a href="http://www.chrisabernethy.com/why-wordpress-asks-connection-info/" title="Why WordPress asks for connection Info">article</a> and its comments helped me reach this conclusion.</p>
<pre><code class="language-bash">sudo su
chown -R apache:apache /vol/html
</code></pre>
<p>I then set permissions to what the <a href="http://codex.wordpress.org/Hardening_WordPress" title="Hardening WordPress Guide">hardening WordPress guide</a> recommends for my html root as all my WordPress files are there as I am running MultiSite with multiple domains.</p>
<pre><code class="language-bash">find /vol/html/ -type d -exec chmod 755 {} \;
find /vol/html/ -type f -exec chmod 644 {} \;
</code></pre>
<p>As apache doesn't have a login I feel this is worth the risk though there is probably a better way to do this. I then added ec2-user to the apache group and changed the permissions of the wp-content folder to have group write permission 775.</p>
<pre><code class="language-bash">useradd -G apache ec2-user
sudo chmod -R 775 /vol/html/wp-content
</code></pre>
<p>This allows FileZilla or any other program logged in as ec2-user the ability to change files and folders in the wp-content folder only. If anyone has a better way of doing this I would like to know. I am only using SSH and SFTP to access the server with key files.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>sFTP using FileZilla into an Amazon EC2 instance</title>
    <link href="https://blog.david-jensen.com/sftp-filezilla-amazon-ec2/"/>
    <updated>2012-01-06T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/sftp-filezilla-amazon-ec2/</id>
    <content type="html"><![CDATA[
      <p>Here is how to SFTP into your AWS EC2 instance using <a href="http://filezilla-project.org/download.php" title="Download FileZilla">FileZilla</a> (this was done on a Mac). Open Site Manager</p>
<ul>
<li>Add site</li>
<li>Host: Ec2 elastic IP</li>
<li>Port: 22 (will sort by default when you select next option)</li>
<li>Protocol: SFTP</li>
<li>Logon Type: Normal</li>
<li>User: ec2-user</li>
</ul>
<p>Open Preferences</p>
<ul>
<li>SFTP</li>
<li>Add Key File select your secure key [.pem] from where you saved it</li>
</ul>
<p>You will need to make sure that the ec2-user has the correct permissions to do the actions you require, here are my <a href="/wordpress-amazon-ec2-apache-permissions-wordpress/" title="WordPress EC2 Apache Permissions">thoughts on the best way to approach this</a>.</p>

    ]]></content>
  </entry>
  
  <entry>
    <title>Install WordPress on an Amazon AWS EC2 Linux instance with persistence to Amazon EBS </title>
    <link href="https://blog.david-jensen.com/install-wordpress-amazon-aws-ec2-linux-ebs/"/>
    <updated>2012-01-03T00:00:00.000Z</updated>
    <id>https://blog.david-jensen.com/install-wordpress-amazon-aws-ec2-linux-ebs/</id>
    <content type="html"><![CDATA[
      <p>I figured that it was finally time for me to roll up my sleeves and get my hands dirty with WordPress running on an Amazon Web Services (AWS) EC2 Linux Micro instance. I know you can use a preinstalled image but I wanted to understand what was going on under the hood so decided to start from scratch. I also wanted to ensure that all data would be persisted to Elastic Block Storage should there be an issue with the EC2 instance. My main coding background is in ASP.NET though I have been managing a team in a Java environment for the last 18 months so this was a reasonably steep learning curve. So I figured that in the spirit of open source and since I was creating a blog that I would share my experiences. My goals were the following:</p>
<ul>
<li>Create Amazon Web Services (EC2) Micro Instance</li>
<li>Setup Apache and MySQL</li>
<li>Install WordPress</li>
<li>Ensure all data is persisted to Amazon Elastic Block Storage (EBS)</li>
<li>Install WordPress Multisite</li>
<li>Map multiple domains to Multisite</li>
</ul>
<p>Amazon very kindly give you an initial <a href="http://aws.amazon.com/free/" title="Amazon Free Usage Tier">free 12 months</a> on one of their micro instances so thought this would be a good place to start. Here are a couple of things to note:</p>
<ul>
<li>EC2 image data does not persist if the image is terminated (either by user or an issue on Amazon)</li>
<li>You can attach an EBS volume to create persistant storage and attach to an EC2 instance</li>
</ul>
<h2>Step 1: Launch an Amazon EC2 Micro Instance and attach EBS and Elastic IP</h2>
<ul>
<li>After registration login to AWS Management Console and go to the EC2 dashboard</li>
<li>Select the closest Amazon region to where most of your traffic will come from (top left)</li>
<li>Select EC2 then Launch Image</li>
<li>I used quick launch the selected Amazon Linux AMI 32bit</li>
<li>Create new security key and download it to a memorable place</li>
<li>Then select Elastic Block Storage - Volumes</li>
<li>Create Volume and make sure it is in the same zone as your Ec2 server</li>
<li>Attach EBS to your EC2 (note the name that it gives your storage)</li>
<li>Select Elastic IP's and allocate new address then associate the address with the Ec2 instance (note IP)</li>
</ul>
<h2>Step 2: Login to your server via SSH and start setup</h2>
<p>I am using a Mac so I just fired up the Terminal and the steps I took are below though if you are using Windows you can follow a tutorial for PuTTY <a href="http://www.powercram.com/2009/07/connecting-to-aws-ec2-instance-linux.html" title="Connect to AWS using PuTTy Windows">here</a>.</p>
<ul>
<li>Fire up Terminal and go to the directory with your .pem key inside</li>
<li>Change the file permissions of the .pem key to 400 by running the below</li>
</ul>
<pre><code class="language-bash">chmod 400 [keyname].pem
</code></pre>
<ul>
<li>You can now login to your server with the following command</li>
</ul>
<pre><code class="language-bash">ssh -i [keyname].pem ec2-user@[elasticip]
</code></pre>
<p>Being a newbie to Linux I had to have a quick look around for the basics of navigation and here are a couple of very basic commands.</p>
<ul>
<li>To see the files in a directory listed in alphabetical order</li>
</ul>
<pre><code class="language-bash">ls -l
</code></pre>
<ul>
<li>to change directory to a path</li>
</ul>
<pre><code class="language-bash">cd /var/www/html/
</code></pre>
<ul>
<li>to remove a directory or file</li>
</ul>
<pre><code class="language-bash">rm -f -r [file-name]
</code></pre>
<ul>
<li>change user to root so you don't have to type sudo each time</li>
</ul>
<pre><code class="language-bash">sudo su
</code></pre>
<h2>Step 3: Setup MySQL with its data persisting to ECB</h2>
<p>Login then change your account to root, then run the server updates.</p>
<pre><code class="language-bash">sudo su
yum upgrade
</code></pre>
<p>Install MySQL.</p>
<pre><code class="language-bash">yum install mysql mysql-server
</code></pre>
<p>Create a filesystem on the attached EBS volume as it currently doesn't have one (I used XFS as the demo I was following did the same) . My EBS volume was called xvdf rather than sdf which the management consoles said  so use what you noted down when setting this up. XFS isn't installed out of the box you need to install and register before you can create the filesystem.</p>
<pre><code class="language-bash">yum install xfsprogs
modprobe xfs
mkfs.xfs /dev/xvdf
</code></pre>
<p>We now need to make sure that this volume is mounted every time we boot the machine by running the following. We then create and mount the drive in this case I have called it vol.</p>
<pre><code class="language-bash">echo &quot;/dev/xvdf /vol xfs noatime 0 0&quot; | tee -a /etc/fstab
mkdir -m 000 /vol
mount /vol
</code></pre>
<p>We now want to create data directories on /vol so MySQL can use these for data storage as they sit on EBS they will be persisted should the instance have an issue.</p>
<pre><code class="language-bash">mkdir /vol/etc /vol/lib /vol/log
</code></pre>
<p>We now need to move the required MySQL files and folders from their default locations to the new one that we have created on /vol.</p>
<pre><code class="language-bash">mv /etc/my.cnf /vol/etc/
mv /var/lib/mysql /vol/lib/
mv /var/log/mysqld.log /vol/log/
</code></pre>
<p>Now that the files have move we can create symbolic links (shortcuts) from where the default files were installed to their new locations on /vol.</p>
<pre><code class="language-bash">ln -s /vol/lib/mysql /var/lib/mysql
ln -s /vol/etc/my.cnf /etc/my.cnf
ln -s /vol/log/mysqld.log /var/log/mysqld.log
</code></pre>
<p>Hopefully everything should be in the right place and we can now start MySQL.</p>
<pre><code class="language-bash">service mysqld start
</code></pre>
<p>If anything goes wrong then check the logs. I would also check the data directories that you created to make sure that you can navigate to them.</p>
<pre><code class="language-bash">tail -f /var/log/mysqld.log
</code></pre>
<p>We now need to change the MySQL root password to be something nice and secure and then run the secure installation as this will be a production environment.</p>
<pre><code class="language-bash">/usr/bin/mysqladmin -u root password '[newpassword]'
/usr/bin/mysql_secure_installation
</code></pre>
<p>Now we need to log into WordPress and create the required tables</p>
<pre><code class="language-sql">mysql -p
mysql&gt; CREATE DATABASE wpdb;
mysql&gt; GRANT ALL PRIVILEGES ON wpdb.* TO wpuser@localhost
-&gt; IDENTIFIED BY &quot;another-new-password&quot;;
mysql&gt; FLUSH PRIVILEGES;
mysql&gt; exit
</code></pre>
<h2>Step 4: Setup PHP, HTTP and download WordPress</h2>
<p>Now it is time to get HTTP and PHP installed by running the following.</p>
<pre><code class="language-bash">yum install httpd
yum install php php-mysql
yum install php-gd
</code></pre>
<p>We need to enable the Apache mod_rewrite module for WordPress to run correctly. I used the command line text editor vim and you can find the cheat sheet <a href="http://www.tuxfiles.org/linuxhelp/vimcheat.html" title="Vim Cheat Sheet">here</a>. You need to change AllowOveride None to AllowOveride All inside the DocumentRoot Directory Directive, normally &lt;Directory “/var/www/html”&gt;</p>
<pre><code class="language-bash">vim /etc/httpd/conf/httpd.conf
</code></pre>
<ul>
<li>vim Cheats</li>
<li>i enables edit mode</li>
<li>esc finishes editing</li>
<li>:wq! writes and saves file</li>
</ul>
<p>We now want to create the html folder on /vol so all of our web files will also be on an EBS volume. We can then do the same as we did for MySQL and remove the folder before creating a symlink from EBS to our EC2.</p>
<pre><code class="language-bash">mkdir /vol/html
rm -f -r /var/www/html
ln -s /vol/html /var/www/
</code></pre>
<p>Now we have a web folder we can download WordPress</p>
<pre><code class="language-bash">cd /vol/html
wget http://wordpress.org/latest.zip
unzip latest.zip
</code></pre>
<p>As I wanted to run a MultiSite Multiple Domain site I needed to have the WordPress files in the root of the web server so the following moves them from html/wordpress to /html and then deleted the /wordpress folder to keep things nice and clean. I also renamed wp-config-sample.php to wp-config.php for ease of editing.</p>
<pre><code class="language-bash">cp -rpf ./wordpress/* .
rm -rf latest.zip
rm -rf wordpress
cp wp-config-sample.php wp-config.php
</code></pre>
<h2>Step 5: Setting up WordPress</h2>
<p>WordPress is a pretty damn easy thing to setup however you do need to edit quite a few files in this step so I thought it would be a good thing to connect via SFTP to allow easy manipulation. Here is a <a href="/sftp-filezilla-amazon-ec2/" title="FileZilla Amazon EC2 SFTP">quick guide</a> to how to connect to FileZilla, once you have done that go to in FileZilla.</p>
<pre><code>/vol/html
</code></pre>
<p>At this stage you will be able to connect and view files within FileZilla but most likely unable to write or create them. This is due to the fact you created all of the files whilst using the root account and the ec2-user doesn't have any permissions to change them. You will need to change permissions of each of the files and folders, you need to use Terminal to all users to write and update them.</p>
<pre><code class="language-bash">cd /vol/
chown ec2-user -R html
chmod 755 -R html
</code></pre>
<p>You will need to change this back at the end anyways but <a href="http://codex.wordpress.org/Changing_File_Permissions" title="WordPress file permissions">here</a> is the WordPress documentation on file permissions to understand what is going on and the risks that you pose should you not.</p>
<p>You can now download wp-config.php and make the below changes</p>
<p>define('DB_NAME', 'wpdb');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'new-password');</p>
<p>define('AUTH_KEY', 'xxx');
define('SECURE_AUTH_KEY', 'xxx');
define('LOGGED_IN_KEY', 'xxx');
define('NONCE_KEY', 'xxx')
define('AUTH_SALT', 'xxx');
define('SECURE_AUTH_SALT', 'xxx');
define('LOGGED_IN_SALT', 'xxx');
define('NONCE_SALT', 'xxx');</p>
<p>$table_prefix = 'wp_';</p>
<p>WordPress provide a very nice helper for the Salts <a href="https://api.wordpress.org/secret-key/1.1/salt/" title="Salt WordPress">here</a>.</p>
<p>Now we need to allow the apache user access to html so WordPress can update plugins and files and change our file and folder permissions to what WordPress recommends <a href="http://codex.wordpress.org/Hardening_WordPress" title="Hardening WordPress">here</a>.</p>
<pre><code class="language-bash">cd /vol/
chown -R apache:apache html
find /vol/html/ -type d -exec chmod 755 {} \;
find /vol/html/ -type f -exec chmod 644 {} \;
</code></pre>
<p>Now lets fire up httpd.</p>
<pre><code class="language-bash">service httpd start
</code></pre>
<p>It is also worth using the below to ensure that httpd and MySQL run on startup.</p>
<pre><code class="language-bash">ntsysv
</code></pre>
<p>Finally you will also need to add a Custom TCP rule to your security groups using the AWS console for port 80 to allow traffic.</p>
<p>Now for the moment of truth, browse to your Elastic IP, should you have any issues you can look at the logs by using the following.</p>
<pre><code class="language-bash">tail 100 /var/log/httpd/error_log
</code></pre>
<p>There is no way I could have achieved the above with out some similar great guides and here they are.</p>
<ul>
<li><a href="http://qugstart.com/blog/amazon-web-services/how-to-set-up-db-server-on-amazon-ec2-with-data-stored-on-ebs-drive-formatted-with-xfs/" title="How to Set up DB server on Amazon EC2 with data stored on EBS drive formatted with XFS">How to Set up DB server on Amazon EC2 with data stored on EBS drive formatted with XFS</a></li>
<li><a href="http://www.ermann.org/2011/03/installing-wordpress-on-amazon-ec2-centos-in-20-minutes/" title="Installing WordPress on Amazon EC2 / CentOS in 20 Minutes">Installing WordPress on Amazon EC2 / CentOS in 20 Minutes</a></li>
</ul>
<p>There are a couple of great guides for Multisite and Multi Domain Mapping below which worked fine for me with WordPress 3.3.</p>
<ul>
<li><a href="http://wordpress.org/extend/plugins/wordpress-mu-domain-mapping/" title="Multiple Domain Mapping">Multiple Domain Mapping</a></li>
<li><a href="http://codex.wordpress.org/Create_A_Network" title="Multisite">Multisite</a></li>
</ul>
<h2>Further Reading</h2>
<p>Since writing this post I have done a lot to my server to optimise the running of WordPress here is some additional reading:</p>
<ul>
<li><a href="/speed-up-wordpress-apache/" title="Speed up WordPress Apache">Speed up WordPress Apache</a></li>
<li><a href="/backup-wordpress-to-dropbox-amazon-ec2-centos/" title="Backup WordPress to Dropbox">Backup WordPress to Dropbox</a></li>
<li><a href="/ec2-centos-reduce-wordpress-hacker-attacks/" title="Reduce WordPress Hacker Attacks">Reduce WordPress Hacker Attacks</a></li>
<li><a href="/speed-wordpress-using-batcache-multisite-memcache/" title="Speed up WordPress Apache with Batcache Multisite">Speed up WordPress Apache with Batcache Multisite</a></li>
</ul>

    ]]></content>
  </entry>
  
</feed>
