Upstream Summer Party

August 16th, 2010 by Alexander Lang

Sorry for the short notice but we have been busy with being on vacation :)

Tomorrow (August 17th 20:00) is the date for our annual summer party. As last year’s location ceased to exist we are moving to the Kiki Blofeld.

Be there and let us buy you a drink or two.

Transactions in CouchDB

July 30th, 2010 by Alexander Lang

So we’ve been told that all these fancy new NoSQL stores don’t support transactions because that wouldn’t scale, and we’d just have to live with that. So yes, technically, CouchDB doesn’t support transactions, yet it still does. In a way.

What CouchDB doesn’t support is transactions that span multiple read/write operations, i.e. write document a, then write document b, if something goes wrong, roll back both writes. What it does support is single document “transactions”, i.e. a document is either written completely or not. So if our application requires a transaction, all we have to do is make sure that transaction happens in a single document.

Here’s our use case: at cobot (our coworking space management service) we have a feature where a coworking space can charge a coworker for a one time service, e.g. usage of a meeting room. The way it works is that the manager of a space goes to cobot and enters an amount and description, e.g. “$10″ and “meeting room”. At the end of the month, a cron job sends out invoices for all the one time charges.

Our problem lies with this cron job. The job has to find all the charges for a coworker that haven’t been invoiced yet, create an invoice and mark the charges as invoiced. Without transactions, if something went wrong between creating the invoice and marking the charge as invoiced, the charge could end up being invoiced twice, because it hasn’t been marked as invoiced the first time.

Clearly we need to throw CouchDB away now and go back to a proper™ (a.k.a. relational) database, right?
Well, no. As I said earlier we can try to move the transaction into a single document.

Read the rest of this entry »

Experimenting with node.js/mite

June 3rd, 2010 by Alexander Lang

Recently on one of my research fridays I decided to work on a problem that’s been bugging us for a long time. We are big fans of the timetracking service mite and use it for all our projects. The problem is that mite is designed around accounts. You can have many users per account, and then you can run reports across all the users that worked on specific projects. On most projects we’re working with independents who have their own mite accounts. Our problem is that we can’t run reports across multiple mite accounts.

Mite does have a nice JSON API though, so there must be a way to fix this. The result of my work is mite.enterprise, which allows you to enter multiple mite accounts and then report on those in one go. You can find the source on github and it’s running at mite-e.upstre.am so you can use it straight away.

While the app itself is relatively simple it posed some challenges I want to share here:

Making multple API requests and still be fast

The way the app works is that every time it needs data from mite it makes all the neccessary queries to the mite api and immediately delivers it to the browser. It doesn’t have its own persistence or cache layer for holding data. In order to keep things fast these requests to the mite API need to run in parallel. While I could have written a standard Rails app and spawn a new thread for every request I decided to try something new: node.js – node is the new cool kid on the block – a server side Javascript framework where everything is handled asynchronously, similar to Ruby’s eventmachine.

In order to run the API requests in parallel I wrote a Javascript function that fires off the requests and collects all the data in an asynchronous fashion:

function DataCollector(no_of_requests, callback) {
  var datas = [];
  return {
    collector_callback: function() {
      return collect_request_data(function(data) {
        datas.push(data);
        if(datas.length == no_of_requests) {
          callback(datas);
        };
      });
    }
  };
};

var mite_client = {
  time_entries: function(params, callback) {
    // go to the mite api and pass the data to the callback
  }
};

var project_ids = [1, 2, 3, 4, 5],
  data_collector = DataCollector(projects.length, function(datas) {
  // do something with the collected data, e.g. send it to the browser
});

project_ids.forEach(function(project_id) {
  mite_client.time_entries(project_id, data_collector.collector_callback());
});

I think it’s best to read this from bottom to top. At the bottom, for every project id that was given to the app (I simplified the code for readability) I ask the mite client for all the time entries for that project. I need to pass the mite client a callback, which in turn gets passed the actual data. Since I don’t want to act on the data immediately but want to wait until all the requests have returned, I’m asking the DataCollector instance for a callback. DataCollector uses a closure so it can collect all the returned data. The data is collected through functions that are created by its collector_callback function that I pass to the mite client where they are used as callbacks. Because the callback functions all have access to the datas array they can push their data on it until enough data is collected – only then the final callback to process the data is called.

While this might seem a little complicated and confusing at first I think it actually is pretty cool. By using all the callbacks the server app never waits for any I/O operations to complete, hence it is lightning fast and can probably handle thousands of concurrent clients.

Storing account data securely

In order to talk to the mite api we need the accounts’ API keys. I didn’t want to have to worry too much about security and how to store this data on the server so I chose a different approach: I’m not storing any data on the server at all. Instead, I’m using the browsers’ local storage. This is a small key value store that most modern browsers support. The data is stored on the hard disk of the client, hence there’s no danger that anyone will steal all the API keys from the server, because they are distributed all across the web.

Another advantage of that approach is that I don’t need a signup/login process for the app. When a user goes to the mite.enterprise site they can start using it immediately. No email address, no password. The app just looks into the local storage and loads the according data.

Nice and fast GUI

I wanted to keep things small and simple, so I decided to keep all the HTML/CSS out of the server. My node.js server only serves JSON and static files. For handling user interactions and rendering templates I’m using the excellent Sammy framework in combination with mustache.js

Sammy is like Sinatra but it’s implemented in JavaScript and runs in the browser. You can map URLs to actions, but instead of loading a new page for every request you do some AJAX requests (or not even that) and then replace whatever parts of the page you want using jQuery.

Conclusions

Node.js is an awesome library. First it lets me implement servers that are fast as hell, secondly I can implement them in the same language I use for the frontend. With local storage I don’t have to implement a signup/login process. Instead, users can use the app immediately and their data is stored on their computer. With Sammy I can quickly put a rich and responsive GUI on top of my servers which only have to deliver JSON. I guess it’s the future™. :)

Oh, and mite just became much more useful for us, too.

Capybara – Mix and match acceptance testing

April 26th, 2010 by Thilo Utke

The more layers you add when testing your application the slower these tests become.

A unit test takes a fraction of a second to run. A simple integration test maybe up to a second. When JavaScript and a real browsers gets involved probably longer. But unnecessary long test runs hurt productivity. Up until a couple of weeks ago I had to make trade-offs either in speed, test-coverage or maintainability of my test suite when it came to real full stack integration/acceptance testing. Here is how I perceive these problems.

A standard Cucumber (a framework to write natural readable acceptance tests) setup uses Webrat which interacts with your app through a simple Rails integration session, so no JavaScript. The best what Webrat could do in this scenario, when it comes to JavaScript, is to recognize some common patterns in your html and send according requests – but still, most of the JavaScript code is not covered.

Webrat can also be used to drive Selenium, which interacts with your web app through a real browser. This will cover Javascript, CSS and possible browser issues. But compared to Webrat Selenium is snail mail slow.

With Culerity or Steam there are alternatives to Webrat which use HtmlUnit: HtmlUnit is a “GUI-Less browser for Java programs”. It models HTML documents and provides an API that allows you to load pages, fill out forms, click links, etc… just like you do in your “regular” browser. They are significantly faster than scripting a normal browser with Selenium at the cost that you don’t see how design works or if any browser issues cause trouble and it is still slower than Webrat without a special backend.

In order to run acceptance tests which require full JavaScript support separately from those who don’t to get shorter test runs I use two separate environments as they are generated out of the box either by Cucumber or Culerity. This leads to duplication of the setup code and step definitions, which means that there is more to maintain and more that could possible break.

Capybara addresses the shortcomings of a two environments solution and still allows you to be flexible in what backend you use for integration testing on a per scenario basis in Cucumber. It does that by using Cucumber’s tags feature.

Capybara “is inspired by and aims to replace Webrat as a DSL for interacting with a web application. It is agnostic about the driver running your tests and currently comes bundled with rack-test, Culerity and Selenium support built in”. In the future we certainly will see other backends. I saw that a backend for env-js (a pure JavaScript browser environment) is a already in the making.

Below is an example that runs one scenario with Selenium and the other with Culerity.

  @selenium
  Scenario: Searching a blog post using autocomplete
    Given a blog post titled "Autocomplete made easy" containing "Some example"
    When I go to the search page
      And I fill in "Search" with "Auto"
      And I follow "Autocomplete made easy"
    Then I should see "Some example"

  @culerity
  Scenario: delete found comments
    Given a comment by author "Thilo"
    Given a comment by author "Tilo"
  When I search for "ilo"
    And I check the element with xpath "//p[contains(@class,'delete')]/input"
    And I press "Submit"
  Then I should see "Are you really sure?"
  When I press "Yes"
  Then I should see "Comments were delete"
  And I should see "0 Comments"

You might have noticed the XPath expression in the second scenario. From time to time you will have to deal with XPath expressions when writing custom steps as XPath is used to locate elements within the DOM. The default steps can be scoped with CSS selectors or XPath, Capybara takes care of the conversion to XPath then.

Using Capybara with Cucumber is straightforward:
First get the gem:

gem install capybara

On OSX you may have to install libffi, you can install it via MacPorts with:

sudo port install libffi

Then go to your rails project and generate the cucumber files as followed:

script/generate cucumber --capybara

And you are ready to go to mix and match your acceptance with tags. For further informations like using capybara without cucumber, asynchronous JavaScript etc. checkout Capybara’s README.

Capybara definitely eases maintaining acceptance test and will give impulses to improve other tools, e.g. env-js.

Are you stuck in a maintenance nightmare or simply want to bring your testing skills to the next level? Get in touch with us.

Product Launch: cobot – coworking space management service

April 1st, 2010 by Alexander Lang

Back in december I attended the “Berlin Coworking Day”, a meetup of the German coworking scene. In the talks I saw a recurring problem was the lack of proper software to help with all the tasks that running a coworking space requires. Since we had been running our own coworking space for a while the problems were not new to me.

So, after a few hours I decided to leave the meetup and start to scratch my own itch. Since upstream was taking the month off anyway I had enough time to play around.

After roughly 4 man weeks of development we released the first version of our coworking space management software at http://cobot.me – it obviously didn’t have a lot of features, but enough to help our own needs.

The basic principle is this: a coworking space owner signs up her space and gets her own cobot site under its own subdomain. There she adds payment plans, payment methods, invoicing details etc. Anyone who wants to start coworking at this space signs up and chooses a plan and payment method.

From then on cobot helps the owner of the space in various ways. It manages payment tracking and invoicing (can be fully automated with Paypal), it helps to keep track of day to day tasks and problems (“the printer ran out of paper”) and provides a platform for communication between coworking space and coworkers.

In addition it allows a space owner to track key metrics of their space. From turnover to occupancy this gives coworking spaces the numbers they need to optimize their plans and the number of coworkers they can fit in.

Even for our small coworking space (which is now full) cobot has made things a lot easier already (we actually know who hasn’t paid yet now). Our next step is to use cobot’s wifi login/presence tracking system so we know how full we really are, and maybe fit in a few more people.

The first guides section of the site.

If you do have a coworking space we hope you hop over to cobot and sign up – you can try it out for free with up to 5 coworkers. After that it’s only 1 EUR/1.50 USD per coworker and month.

(If you want to follow along the development, there’s twitter account (@cobot_me) and a blog.)

From Journeyman to Client

February 13th, 2010 by Alexander Lang

Agile project management makes the client an integral part of the development process. This article explains what your responsibilities and powers as a client are, and helps you to understand project management the way we see it.

In the traditional (waterfall) model of software development someone writes a specification of the whole software and then the programmers fail to implement it within the given time/budget. To be honest I don’t know a lot about this way of doing software, but I’ve seen it fail.

But I do know a bit about how we write software. In contrast, agile development works in small steps. There is no upfront specification, as we acknowledge that this specification would be incomplete and quickly outdated by changing requirements. Instead we work in short iterations (at upstream typically ~2 weeks) where we only plan ahead for a short amount of time.

By aggressively prioritizing what is most important we are able to release software that fulfills the needs of the business with less clutter in a shorter amount of time.

For me this sentence is really the essence of agile project management as it shows its most important point: prioritizing what is important for your business.

What is software the fulfills the needs of the business? It’s a software that solves your specific problem. If you want to sell something online it allows your customers to click a buy button. If you need to send invoices it will put a bunch of numbers on a sheet.

What is less clutter? Less clutter means if you want to sell something online it neither has a tag cloud nor a facebook like wall for every product where users can post their video reviews. If you need to send invoices it will not let you upload pictures for it.

What is less time? Less time means we deliver your product faster because we spend less time on implementing features because there are fewer features. It does not mean that we can program faster because we are doing agile (seriously we can’t).

What is prioritizing? You do the things first that are most important.

So what is important? And here is where it gets difficult.

What is important is your – the client’s – decision. The problem is that a lot of things can be (thought of as being) important. For a web site, the start page has to have a maximum conversion rate, SEO is important, scalability is important (isn’t it?), usability is important, choice of technology is important, the database schema is important… you get the idea.

But do you know what’s really important? That your business problem is solved. And do you want to know how many kinds of business problems there are? Well, there’s exactly one: make (more) money.

I think it actually is that simple, but from what I’ve seen it can become really hard to focus on that one goal, when you think you have to consider all that other stuff as well, but let me say this again: as a client it’s not your responsibility to think about the database and scalability (you won’t have to scale in the beginning). Your one and only problem is: how do I make money with this. Everything else comes after it.

A good way to focus on solving that problem might be to ask yourself this question: How do I make (more) money?

Case Study

Let’s stick to the example of an online shop and let’s assume you want sell e-books. Of course you look at the competition first, and there is amazon.com. They sell e-books and from what it seems they are making a whole lot of money from it, so that must to be a good starting point. From their site you collect a bunch of requirements you also want in your shop:

  • Categories: Books must be in categories so people can find them.
  • Tags: With tags people can click on tag clouds and then see all the books to that tag.
  • Related books: “People who have bought this might also like…” – I love that feature
  • User reviews/ratings: when users review the books we can make a top list and then everyone will buy the top books.
  • Licensing: You have talked to the publishers already and they have these complicated licenses where you may only sell a certain book in a certain country but only at full moon when it’s raining – so the shop needs to take all this into account.
  • Internationalization: We need at least English, Spanish and Mandarin to reach more markets
  • Statistics: You want to know at what time and weather conditions people buy books from where, on which browser and operating system and which IP address they used to do it. From that data you will be able to optimize the hell out of the start page.

So, that looks like a reasonable list of requirements doesn’t it? With this shop you could steal a nice market share from amazon right? Well, let’s take that list to the test: does it help me to make money?

  • categories: no
  • tags: no
  • related books: no
  • reviews/ratings: no
  • licensing: no
  • internationalization: no
  • statistics: no

Surprised? I hope at least a little bit. So what would make you some money?

In order to make money
as the owner of the shop
I want people to buy a book

With all the fancy features above you forgot (sorry, I forgot) the only important feature of the site: a button that says “Buy this e-book”. By the way the format of that feature request comes from the BDD (behavior driven development) people. This is the generic template:

In order to <business value>
as <role>
I want <feature>

This is a brilliant template that you can use to take all your feature ideas to the test. Remember that the only valid business value here is to make money. And that the only role that is important here is you as the stakeholder of the project.

Let’s look at your features:

Categories

In order to make money
as the owner of the shop
I want categories

How is a category going to make money? A category is a means to, well, put your books into categories. You might at some point decide that you can sell more books by putting them into categories because that big list of 1000 books on you start page crashes people’s browser and they can’t buy your books anymore, but for now you haven’t even sold a single book yet, so categories are definitely not going to make you any money right now.

Tags

A few years ago someone declared that if you want to be “Web 2.0” you need tags. That’s why a lot of websites have tags nowadays. Like categories you can’t make any money out of tags.

Related books

While this is a popular feature at amazon, your yet to be launched shop wouldn’t even have enough data at the beginning to make any sensible claims about what books are related. Again, at the beginning this won’t matter at all. You can always add it later, when the money making assertion becomes true.

Reviews/Ratings

While reviews can be a good way to promote books and build trust for your customers, when you launch your site there won’t be any reviews because nobody has bought a single book yet. So unless you charge people for being able to write reviews this is not going to pay your rent.

Licensing

Sure, we can build you a system that grabs the weather from weather.com, can calculate the moon phases over the sahara and figure out people’s countries by their IP address, but it’s going to cost you. How about this: You start and market your shop in only one country. This can be your home country or the country with the simplest licensing model. After you have sold enough books there we can start working on the rest (and you can pay us from the money you have made already).

Internationalization (I18n)

Again, we can build you any system you want, but be warned, some people read and write from right to left or top to bottom. WIth I18n you are opening a whole new can of worms. How about we do I18n later, after you have proven that your business model works in one country (or language region, which might cover a lot of countries (thinking English/Spanish/Mandarin)).

Statistics

Sure it’s important to measure the success (or failure) of your business. But before you have a business there isn’t really much to measure is there? And how about this: for now every time someone buys a book you open up your spreadsheet app on your computer and put a date and a price in it. I know it may seem archaic but it works. If you want to go crazy you can even use a real book made of paper, but since you’re selling e-books you probably don’t want that.

All these examples boil down to this: test your features agains the BDD template: can I make more money now when we implement this. A lot of them are really not that important now and you can use something simpler instead.

Conclusion

Deciding what is important is the one big way that you can control the project. Programming takes time and we don’t usually have a lot of ways to make that faster within a project. But choosing wisely the features that you really really need to start selling your products can make the difference between a 4 week and a 6 months project. We do the best we can to help you with those decisions but ultimately they are yours.

If we spend 6 months working on your project and it’s still not done then that’s not a programming problem, it’s a management problem, because we have been working on too many features, of which many probably weren’t as important as you thought (no offense). On the other hand if we make it in a few weeks, we’ll congratulate you and bring some drinks to your early launch party.

(On a side note we recently released cobot.me after only 4 person weeks of development it doesn’t have a lot of features, but that’s a different post.)

Git meets Tracker, a possible Workflow

January 17th, 2010 by Thilo Utke

When working with our clients we use pivotal tracker to manage requirements and priorities. Which works very well, as it keeps overhead low and offers a very focused communication channel for feature related questions.

The last step for a successful delivery of a feature requires our customer to accept that feature or hand it back to us if something isn’t satisfying. To enable our customers to do that we provide them with a staging environment, which is a non public version of our customers’ product with the latest code integrated so that he can try out new features before they go live. We deploy to the staging system directly from the master branch usually, from time to time we introduce feature branches if we think something takes longer or might need refinement after more customer feedback. By the time of an actual live deployment we normally have ironed out any remaining issues which shown up during the client’s review on the staging system.

This simple system works pretty well and effective if you are in control of the staging environment, have only one person as the customer to talk to and your developers’ communication works like in a hive mind (which it does, mostly :) ). This system reached its limit when we worked with PaperC lately, one of our valued clients.

We coached their programmer in BDD and pair programming some time ago and still working with them very closely to get improvements and new features out of the door fast. The limits with our simple workflow became visible when I paired with Patrick together for PaperC and they also had a pair on site with us at co.up. At first delivered tickets began to stack up waiting for acceptance, also because the staging system became unstable as issues weren’t fixed fast enough.

Things got more complicated as we put features on staging which weren’t supposed to make it into the next live deployment as they where part of a bigger, not yet thought to an end, interface change. These features just should be shown in action to see how things can go on from what we did so far. This incident cost us some extra time to put these feature related commits out of the master branch into a feature branch. So we switched to create a feature branch for everything that was more than “add a new input field to that”. This left us with a lot of branches we had to keep track of when deploying to the staging system, but at least we could undo merge commits easily when a feature wasn’t suppose to be deployed live. Then we started a discussion on how we could do this in a better way. Before I describe the workflow which I think is best suited, as we already employed it successfully in the past, I’d like to mention two suggestions I’m not comfortable with an why.

One idea was the introduction of pair branches, where every pair commit their work to. And these branches would be merged into master for acceptance. Apart from not really resolving the issue, it just mitigates it onto a pair branch, and it contradicts the principle of collective code ownership.

Another proposal was to create a special production branch and selectively cherry-pick commits which are supposed to go live. This points into the right direction, as it gives you more control of what goes live, but it might leave you with a lot of commits to pick from, if you have a developer like me who commits rather often. And it doesn’t give you a single point to roll back from if a feature that has multiple commits get pulled off the release.

So now for my preferred and practically proven solution. First off, it requires an extra server which I refer to as experimental. It is a lightweight (not so close to production setup) staging system with a database schema that should be easily migrate-able up and down like on a CI server. It should be fed with some test data automatically. It doesn’t have to be as much data as on staging, just enough to try out most features.

Now to the git workflow part. Smaller changes and bug fixes go directly to master as always. Bigger features should be done in separate branches and merged to master once things are done (Don’t forget to delete the remotes if the feature gets accepted). The master branch should be deployed to the experimental server at least once a day, likely more often so that features can be quickly accepted. Features that aren’t necessarily ready for production yet can be deployed to experimental for acceptance testing simply by changing the branch from which the experimental environment should be deployed from the master branch to the feature branch and rebuild the database if required. Before an imminent release the master should be pulled to staging so that any remaining issues can be fixed. Such fixes should happen on the staging branch and can later be merged back to master. If everything is fine, merge staging to production and deploy to the live system if you are ready. This way you always have a clean production branch, it’s easier to pull off features from a release and get faster feedback for completed features without worrying to mess up the next production release.

What is your approach to managing commits and releases? Do you find this post helpful? Feel free to leave some feedback in the comments.

Upstream spreading to Scandinavia

January 12th, 2010 by Alexander Lang



The Upstream Locations - please zoom out until you see Australia

As of last week upstream is now present in 2 more countries: Finland and Sweden. We see a strong increase in the web development market in the scandinavian area so we want to be there before the rest of the world notices. Ok ok, so actually that’s not the reason. Both Frank and I moved for personal reasons.

Frank is now situated in Turku, Finland and I’m in Lund, Sweden. We will both be staying there for about half a year and continue to work for upstream remotely. As our company pair programs all the time so are we – only remotely now, using iChat’s screen sharing/audio chat and good old Textmate. It actually works smoother than it did when we tested it in the office’s wireless network. Scandinavian communication infrastructure is pretty good.

While we are here in the north we will be attending and possibly speaking at a few conferences in the area like Nordic Ruby and the Scandinavian Web Developer Conference (SWDC).

If you are interested or know anyone who would want to hire us for a web project either in Sweden or Finland please drop us a note. While remotely working for the Berlin office is ok it would be nice to work on our own. We create high quality, fully tested webapps in a few week’s time, we help with code quality and scalability problems, we can do training/coaching on various programming/agile topics, remotely or on site.

Oh and if you don’t have a project for us but live in the area say hi so we can invite you for a beer or two. :)

Time-out

December 2nd, 2009 by Alexander Lang

Upstream is taking the december off. Except from support for running projects we haven’t taken on any new projects for this month. The reason is that we wanted some time to think about the future of our company, but also to have time for other things.

We have already done this for a weekend in January when we went to Maine. It was a fun weekend but we spent a lot of time walking around at the beach and in the sauna, which left too little time for developing any significant ideas. So this time we are doing it for a whole month.

For the thinking part we will be doing a few meeting throughout the month to talk about different aspects, like the kinds of customers we want to attract in the future, the kind of work we want to be doing, how much and where we will want to work and also how much money we want to be making with all this. We are not going to do any fancy brainstorming-like things. Instead everyone spends their time doing whatever he or she thinks will produce the best ideas – be it sleeping in every day, long breakfasts or running around in the park. We will then gather occasionally to collect and exchange ideas.

For the “doing other things” part: first of all we want to give our new office and coworking space some love. The walls are all white and empty yet and there are still a few ikea boxes stacking up. Another part is to attend some of the many events Berlin has to offer, but that we mostly have to skip because of work.

I already spent yesterday at the coworking day, where Germany’s coworking community gathered to discuss the issues of setting up and running coworking spaces. That was my first day off and I already got a few new ideas from it that could help upstream in the future. Next up is TedX Kreuzberg, where the smart people of Kreuzberg will come and tell us about their brilliant ideas. I’m very much looking forward to that.

I will report back on our progress here from time to time. So far I can only say: “Please try this at home”. Not having to worry about projects and day to day problems all the time is very refreshing and I am confident 2010 will be a great year for us.

Upstream on the Move

November 15th, 2009 by Thilo Utke

Upstream on the MoveWe just moved into our new office at Adalbertstrasse 7, 10999 Berlin, the old one just got too small. Too small for Upstream and too small to offer a good co-working experience. During the last years, also with the help of our co-working space, we were able to grow our network of skilled freelancing professionals which allow us to do more and bigger projects and offer our customers the best people for the job.

We had a good time with our old office. For example we co-worked together with Jan Lehnardt (@janl) of CouchDB fame, taught Ruby and TDD to then still new developers like Lena Herrmann (@kilaulena), found skilled developers like Patrick Hüsler (@phuesler), found great designers like Kristina Schneider (@kriesse), won good PHP Developer like Robin Mehner (@rmehner) over to Ruby, ran DevHouses and Cockpit Nights to learn and share, coded with international recognized personalities like Pat Allan (@pat), had lots of well known guests in our office and some good parties too. But the old upstream office just got to its limits. I’m happy that all our co-workers moved with us.

The new office will allow us to keep a productive and inspiring work environment, which I think is essential to deliver great products, and evolve all the great things we did so far. For example Alex will expand our efforts in providing an affordable space for independent workers that combines a relaxed and social atmosphere with the infrastructure and productivity of a well equipped work place with co.up (@co_up). This way I think we will improve our network even further and get peoples and ideas together for the best outcome possible.

Another great thing about the new office is that its interior and its central location next to Kottbusser Tor underground station allow us to keep hosting the Ruby User Group Berlin meet-up as part of our involvement in the local developer scene.

So if you are in need of a desk (see co.up for details), want to get in touch with the tech scene or are looking for skilled people for your project, visit us in our new office.

I look forward to a great time with more great people and hope that our recently started community photo wall will grow fast with photos of well known and yet not so well known faces.