Using multiple databases in Laravel for all queries

As we continue to grow our hosted Invoice Ninja platform we’ve been been looking into both vertical scaling [bigger servers] and horizontal scaling [more servers].

Initially we added more web servers using a load balancer. This was relatively easy to setup and as an added bonus provided higher availability. Over time however we’ve started to see our single database server experience increased memory usage, particularly after releasing our mobile apps.

Our plan was to simply divide our users across multiple databases. One database would function as the lookup server, the other databases would store the actual data.

Searching Google for ‘multiple databases in Laravel’ mainly returns examples of either specifying the connection for the particular query:


Or defining it in the model by setting:

protected $connection = ...;

However, if you’d like to use a different connection for all queries you can use:

config(['database.default' => ...]);

For our implementation we created a middleware class to find the database server with the provided credentials. The server is stored in the cache so the lookup is only required once every two hours, this is particularly helpful for the API where there’s no session.

To keep the lookup tables up to date we’re using Eloquent creating and deleted model events. Finally, to ensure our queued jobs use the right database we’re using Queue::before(...) to set it.

Developing a bot for the Microsoft Bot Framework using PHP

We recently released our first version of our Skype bot, I thought it might be helpful to share some of our implementation details.

Our bot enables users of Invoice Ninja to easily create, update and email invoices as well as list their products. The code for the bot is available on GitHub.

Here’s an example:

invoice acme for 2 tickets, set the due date to next thursday, the deposit to 5 dollars and the discount to 10 percent

LUIS is able to parse the command into its distinct parts.


Our app can then process the intent and return the invoice.


Two core benefits to natural language input can be seen in the example:

  • Dates can be easier to select as text. I’d much rather input ‘next thursday’ than have to find it in a cramped data picker.
  • We’re able to expose fields through multiple terms. In our standard interfaces each field needs a single label however with speech we can assign multiple labels, in this case ‘partial’ and ‘deposit’.

Microsoft provide helper libraries for C# and Node but the core features are available through a REST API. When getting started I found this article to be extremely helpful, it covers authenticating with OAuth and sending messages using PHP.

LUIS can handle matching intents but the client and product names need to be matched in our app, to accomplish this we’re using a combination of similar_text and metaphone to select the best match.

When we deployed the bot to production we found that getallheaders() wasn’t available, this solution enabled us to access the authorization token.

If you have any questions comment below.

Using a foot pedal for ctrl and alt modifiers on Ubuntu

I’m a big fan of my DataHand (or one of these) but overtime I’ve found the Ctrl and Alt modifiers a bit uncomfortable.

One of my favorite hotkeys is to use the ctrl key with left or right to move between words but that has me regularly holding down the key.

The solution I’ve found is to use a USB foot pedal, here are the steps to set it up on Ubuntu.

First use evtest to determine the /dev/input/event number and the button codes

/dev/input/event16: OLYMPUS CORPORATION HID FootSwitch RS Series
Select the device event number [0-16]:
Event: time 1456855230.136267, -------------- SYN_REPORT ------------
Event: time 1456855230.528267, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90011
Event: time 1456855230.528267, type 1 (EV_KEY), code 272 (BTN_LEFT), value 0
Event: time 1456855230.528267, -------------- SYN_REPORT ------------
Event: time 1456855230.872269, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90012
Event: time 1456855230.872269, type 1 (EV_KEY), code 273 (BTN_RIGHT), value 1

Then use evrouter to map the buttons by creating a file called ~/.evrouterrc with the following contents (you’d likely need to update the values).

"" "" any key/272 "XKey/Control_L"
"" "" any key/273 "XKey/Alt_L"

And then run evrouter

evrouter /dev/input/event16

Sites to help predict future trends

One of the challenges working as a programmer is keeping up with new technologies. Although many appear promising if you decide to spend the time to learn something new it needs to pay off in the long run.

There are two sites I primarily use to help decide, I consider both to be good leading indicators of the future success of a language/framework/library/etc.

All technologies will eventually go out of date, the challenge is picking ones that will hang around for a while.

Laravel: TokenMismatchException error

A common cause for this error (assuming you’re correctly passing along the form token) is the form session expiring. This chunk of code will warn the user when the session is about to expire and enable them to extend it by making a simple get request.

Note: you’ll need to add a /keep_alive route which return ‘success’ (or any other value).

<div class="alert alert-warning" id="keepAliveDiv" style="display:none">
    This page will expire soon, <a href="#" onclick="keepAlive()">click here</a> to keep working

<script type="text/javascript">
    var redirectTimer = null;
    function startWarnSessionTimeout() {
        var oneMinute = 1000 * 60;
        var twoMinutes = oneMinute * 2;
        var twoHours = oneMinute * 120;
        setTimeout(function() {
        }, (twoHours - twoMinutes));

    function warnSessionExpring() {
        redirectTimer = setTimeout(function() {
            window.location = '{{ URL::to('/dashboard') }}';
        }, 1000 * 60);

    function keepAlive() {
        $.get('{{ URL::to('/keep_alive') }}');

    $(function() {

Lessons Learned – Part 1

When I think back to when I just started working as a programmer I distinctly remember thinking I knew what I was doing. Almost 15 years later I now have the experience to know how wrong I was. We learn from failure and over the years I’ve had the chance to learn a lot.

I can never forget (still trying…) my first major screw up. I was just a couple of days at my new job working on a mailing list solution for a custom CRM. I had temporarily added a line of code to force the test emails to just be sent to my address. A few hours later my boss asked me to make an adjustment. While working on it he asked me about an email he’d received. Of course I’d forgotten to put back the line of code and had sent my test email to all 200,000 users.

Part of this was likely hubris, how could I possibly forget to set this insanely important line of code. Of course everything that can go wrong will go wrong. I had been testing with some pretty stupid emails, messages to myself and that sort of thing. Luckily the email the went out was just the word ‘test’. Mistakes will always happen, we need to create environments which prevent them.

Looking back this clearly should have been an environment setting. Laravel has an extremely useful ‘pretend’ setting in the email config file which prevents any emails from being sent, writing them to the log instead.

I’m a strong believer in the value of mistakes. Fool me once shame on you, fool me twice shame on me. The scars we get when bad things happen never fully heal which thankfully serve as reminders in the future. I’ve probably become a bit too paranoid now (especially when working with emails) but I’m sure it’s for the better.

Sign up below to be notified of future posts in the series or follow me on twitter @hillelcoren.

Food For Thought

This post may seem a bit out of place on the blog and I guess that’s because it is. In a nutshell: I got sick, I learned how to eat and I got better. These are my current thoughts on food and nutrition. We’re all different, as always do what’s best for your snowflake of a body.

There’s always talk of low carb or high protein or zero fat or … but they’re missing the point. It’s not one versus the other it’s which of each.

We’ll start with fats. Coconut oil for high heat cooking and olive oil for low heat cooking. We’re starting to accept the myth that saturated fats are bad was just wrong. They’re stable and hold up well to high heat, if your oil is smoking throw it out.

As a questionable runner up I’ll mention Canola oil. It’s low in Omega-6 fats but it’s heavily processed. You get olive oil by squeezing the olives, the process for canola oil is a bit more complicated.

For protein, meat’s important but most of us eat too much of it. Organic makes a lot more sense here as you’re higher up the food chain but it can get expensive.

We’ve been ingrained with the belief that processed foods are bad, but the positive approach is to aim for high nutritional density. Kale gets it’s great reputation because it’s at the top when compared this way.

Eggs got a bad wrap, they truly are a super food. Most of the cholesterol in our blood is made by our body. A far more important indicator is the ratio between the types and densities of cholesterol.

I can always judge how well I’m eating when I’m standing at the checkout lane at the supermarket. The basic idea with shopping is to mostly buy from the perimeter of the store.

What we don’t see when we buy our food is all of the bugs in it. We’ve become a germ phobic society but only 10 percent of the cells in the body are human. I like the quote that antibiotics were the science of the 20th century while probiotics will be the science of the 21st century.

It’s good to eat your vegetables with meals raw, cooked and fermented. Raw sauerkraut and pickles are a great source of natural probiotics.

With fiber it’s important to note the difference between soluble and insoluble fiber, the former slowing you down while the latter speeds you up. Psyllium seed powder is a great natural form of soluble fiber.

Two common food triggers to watch out for are gluten and dairy. The best way to check for a sensitivity is to eliminate it for 30 days and then add it back for a few days in a row.

The trouble with gluten is more accurately an issue with Zonulin (sounds like a bad guy from a Superman comic) which can loosen the gut lining.

Most people can digest dairy when younger but many lose the ability as they get older. It’s akin to losing our hearing as we get older but digestive health and genetics plays a role.

Bone broth soup is one of the single best foods you can eat. Some frozen veg (brocoli, colifower, carrots, etc) boiled in broth and then pureed with a hand mixer makes a great soup. Maybe add a bit of coconut milk and some salt & pepper.

%d bloggers like this: