Examining the Glastonbury Ticket Sales Website

Tomorrow is that time of year again, when hundreds of thousands of people spend hours pressing their F5 key, in an often futile attempt to try to book Glastonbury Festival tickets.

Although I have been successful the last couple of years anyway, this year I had the opportunity to do a bit of investigation beforehand, as they had a smaller ticket sale on Thursday evening.  Since we have baby in tow this year, will be caravanning, and couldn’t buy a coach ticket, but I could use the opportunity to check out the SeeTickets servers, and get an idea how their pages and queuing system work.

This is also more important, since 15,000 of the tickets have already sold, there will be less available tomorrow than on previous years.

When I first hit the site, right on the dot of 6pm, I refreshed a few times, and immediately got to the coach ticket selection page.  Here, you got to choose between Wednesday, and Thursday departures.  I clicked Wednesday, and immediately got a registration numbers form.  I was impressed – in the past I’d been stuck in a queue for a long time before being able to type my reg numbers in!

So, I saved the page, so I could have a look at it later.  I clicked through, and had a look at all the pages, including the payment page.

Over the next half an hour I refreshed the page a few times, until I got added to the normal queuing system.  This is a javascript based refresh which refreshes every 20 seconds, and polls the server for a booking slot.  I assume they use a session based queuing system, because although last year there were problems after typing in the registration numbers (because of a DNS configuration issue), the previous festival, once I got through to this screen, I had no further issues.

Looking at this then, it’s fairly simple on how to get your booking slot – you keep refreshing the page until instead of showing you a queuing message, you get a page where you type in the registration numbers.

What you are actually hoping the see, is this form:

<span data-valmsg-for=”RegistrationErrors” data-valmsg-replace=”true”></span><form novalidate=”novalidate” action=”/event/addregistrations” id=”mainRegForm” method=”post”><input id=”showCode” name=”showCode” value=”800004″ type=”hidden”>            <h3>YOUR DETAILS</h3>
<div>
<label>Registration Number: </label><input id=”registrations_0__RegistrationId” maxlength=”30″ name=”registrations[0].RegistrationId” type=”text”><span data-valmsg-for=”registrations[0].RegistrationId” data-valmsg-replace=”true”></span>    <label>Postcode: </label><input id=”registrations_0__PostCode” maxlength=”30″ name=”registrations[0].PostCode” type=”text”><span data-valmsg-for=”registrations[0].PostCode” data-valmsg-replace=”true”></span>
</div>
<h3>ADD UP TO 5 ADDITIONAL TICKETS</h3>
<div>

<span>#1</span>
<label>Registration Number: </label><input id=”registrations_1__RegistrationId” maxlength=”30″ name=”registrations[1].RegistrationId” type=”text”><span data-valmsg-for=”registrations[1].RegistrationId” data-valmsg-replace=”true”></span>    <label>Postcode: </label><input id=”registrations_1__PostCode” maxlength=”30″ name=”registrations[1].PostCode” type=”text”><span data-valmsg-for=”registrations[1].PostCode” data-valmsg-replace=”true”></span> <div>&nbsp;</div>                         <span>#2</span>
<label>Registration Number: </label><input id=”registrations_2__RegistrationId” maxlength=”30″ name=”registrations[2].RegistrationId” type=”text”><span data-valmsg-for=”registrations[2].RegistrationId” data-valmsg-replace=”true”></span>    <label>Postcode: </label><input id=”registrations_2__PostCode” maxlength=”30″ name=”registrations[2].PostCode” type=”text”><span data-valmsg-for=”registrations[2].PostCode” data-valmsg-replace=”true”></span> <div>&nbsp;</div>                         <span>#3</span>
<label>Registration Number: </label><input id=”registrations_3__RegistrationId” maxlength=”30″ name=”registrations[3].RegistrationId” type=”text”><span data-valmsg-for=”registrations[3].RegistrationId” data-valmsg-replace=”true”></span>    <label>Postcode: </label><input id=”registrations_3__PostCode” maxlength=”30″ name=”registrations[3].PostCode” type=”text”><span data-valmsg-for=”registrations[3].PostCode” data-valmsg-replace=”true”></span> <div>&nbsp;</div>                         <span>#4</span>
<label>Registration Number: </label><input id=”registrations_4__RegistrationId” maxlength=”30″ name=”registrations[4].RegistrationId” type=”text”><span data-valmsg-for=”registrations[4].RegistrationId” data-valmsg-replace=”true”></span>    <label>Postcode: </label><input id=”registrations_4__PostCode” maxlength=”30″ name=”registrations[4].PostCode” type=”text”><span data-valmsg-for=”registrations[4].PostCode” data-valmsg-replace=”true”></span> <div>&nbsp;</div>                         <span>#5</span>
<label>Registration Number: </label><input id=”registrations_5__RegistrationId” maxlength=”30″ name=”registrations[5].RegistrationId” type=”text”><span data-valmsg-for=”registrations[5].RegistrationId” data-valmsg-replace=”true”></span>    <label>Postcode: </label><input id=”registrations_5__PostCode” maxlength=”30″ name=”registrations[5].PostCode” type=”text”><span data-valmsg-for=”registrations[5].PostCode” data-valmsg-replace=”true”></span>                </div>
<input value=”Proceed” id=”add_registrations” type=”submit”>
<p><a href=”javascript:void(0)”>Clear registration form</a></p>
</form>    <script type=”text/javascript”>
window.onload = function () {
registrationValidator.init($(‘form#mainRegForm’),
6,
‘#registrations_{0}__RegistrationId’,
‘#registrations_{0}__PostCode ‘);

$(‘.clear-form’).click(function() {
if (confirm(‘Are you sure you want to clear the registration details form?’)) {
$(‘.add-registration input[type=”text”]’).val(”);
$(‘.add-registration .field-validation-error’).empty();
}
});
};
</script>

Pretty straightforward – it’s a basic HTML form which submits to /event/addregistrations with the POST data you provide.

So, is there a way to avoid hitting F5 over and over?  Well, perhaps – but I suspect trying to submit directly to this URL with the POST data would be a mistake.  I neglected to check, but I expect by this point, I already had a session ID on the server, and this would be included with the HTTP post in the headers.  I imagine, without this, the request would just be rejected.  This is at best – if they have any paranoid security software, you might end up getting your IP banned, which we really don’t want, at least, before we’ve got tickets.

So, what if we hit the queuing system?  Will the refresh every 20 seconds be enough?  I think not.  The issue with this is that you only get one chance to get a booking session every 20 seconds – and you just have to be lucky with that.  Since there are likely half a million other people or more trying to get one too, your chances are very limited, if you just refresh once every 20 seconds.

To get a better idea how they keep sessions, I had a look through the cookies created by the glastonbury.seetickets.com site.  One is an ‘NRAGENT’ cookie, which looks to be related to the newrelic monitoring agent they are using – good bit of software actually.  One is more interesting – it’s called X-Mapping-xxrandomdata.  A quick google reveals that this one is set by the Stingray Traffic Manager software, which is used for load balancing.  Interesting.

So that tells us, that it is most likely that in front of backend web/application servers are a couple of load balancers.

Other cookies are _utma, _utmb, _utmc, _utmz, these are all for Google Analytics, so we can ignore them.  Finally, there is a cookie called SeeAffiliate, with content id1umg.  I’m not sure what this is, but it expired back in September, so I think it must have been an old cookie from a previous visit.  The X-Mapping cookie looks like the only one of significance here.  However, I am checking several days later, so my session cookie may well have disappeared now.

Looking at the DNS records, there were two IPs for the ticket booking servers.  So, if they are using load balancers, there are likely two, one for each IP address.

Seeing as there are two IPs, this provides a simple round-robin load balancing, where clients only resolve one address at a time, and therefore get sent to one frontend load balancer or another.  Looking at the dig record more closely, they have the TTL value set to 60 seconds.  At least – I thought they did.

Looking at the BT nameserver, things are slightly different now – the TTL is ticking down, each time I hit it:

glastonbury.seetickets.com@194.74.65.69 (British Telecom (UK)):

glastonbury.seetickets.com. 25	IN	CNAME	seetickets.com.
seetickets.com.		13	IN	A	194.168.202.201
seetickets.com.		13	IN	A	194.168.202.218
seetickets.com.		13	IN	A	194.168.202.202

The TTL here is 13 seconds, and each time I hit it, it decreases and then goes back to 60.  This only happens on the BT server though, not Google or any of the others I tried.  Perhaps something specific about the BT DNS server?  Or perhaps a special DNS setup for Glastonbury?  I’m not sure.  The only advantage I can see to this short time-to-live setting is that client requests are distributed evenly across the IPs.  This is probably useful to them, but perhaps not always to us.  It does mean that if one server goes down though, you won’t have to wait too long before you hit the next one.

They’ve also added a new server since several days ago, .218.  In addition, glastonbury.seetickets.com is just a CNAME to seetickets.com, so you are probably hitting the same IPs as the rest of their ticket booking too.  Hmm.
I did a reverse DNS lookup on the IP records to find out a bit more.  It looks like they are being hosted by Virgin media, or at least are on their network.  Great!  I am on Virgin Media too.  See Tickets are a Nottingham company, and I am also in Nottingham.  This bodes well for latency issues.

I tried pinging servers, but they are not responding to ICMP at the moment.  This is probably a fair precaution – they are going to be busy enough as it is, without having to send back thousands of pings a second to geeky IT people like me.  Unfortunately, this makes it difficult to check our latency.  We can instead use netcat to check how long it takes to establish a TCP connection to each of the IPs:

Right, so now we want to reduce lag as much as possible, and get latency as close to zero as is possible.

First port of call, plugin to our ethernet switch.  WiFi adds quite a bit of latency – testing to our own router, it averages 3-5ms on Wifi, going as high as 56ms at some points.  On cabled LAN it’s <1ms.  Ok, so we have bought ourselves a few milliseconds per requests with little effort.

Now, the basics, lets speed up the computer(s) as much as possible:

  • Close all other programs except the browser
  • Close the other tabs and windows on the browser
  • Disconnect phones and other devices from your network to avoid things leeching bandwidth
  • Disable all browser plugins, except perhaps Check4Change (as below)

Now the setup – we have three IPs, so perhaps three computers hitting all of them would work best.  Unfortunately there are only two of us, and neither of us want RSI from hitting F5 over and over.

So, bring in the Check4Change firefox extension, which seems ideal for this situation.  It reloads the page on a configurable time period, and checks for a change to an area of the HTML.  This means it isn’t just a ‘blind’ reloader plugin – some of them refresh over and over, but don’t know when to stop.  I had no luck with these last year, and I think they just made things harder.

The great thing about Check4Change is that you can check to see when a bit of text in the page has changed – it will then alert you, and flash the tab to let you know.  Excellent!

So, after installing the plugin, we’ll test it out.  At present, the site says ‘check back on Sunday’.  So, I highlight ‘check back’ and right click, turn on Check 4Change.  You can configure timeout periods – perhaps 1 or 2 seconds is what we want.

Great, it seems to be very quickly refreshing the page – I can’t see what it’s doing at all, it’s so quick.  This is not reassuring, so I think perhaps I will test it on another page which I know to be changing.

Time for that later – firstly, we need to assemble the information we need.

  • Get all registration numbers and associated postcodes you are booking beforehand.  Put them in a text file for cutting and pasting.
  • Have your DEBIT card (or credit card if you are booking internationally) to hand.  Tickets are not confirmed until payment is taken, so you need to be able to do this very quickly.
  • Make sure there’s enough available in your account for all the tickets – you don’t want your payment to be refused and lose your tickets at the last moment.
  • Have computers setup, fully charged.
  • Have drinks and snacks to hand – you may not be moving for 3 or 4 hours.
  • Start bright and early, give yourself time to setup.  Visit the site earlier than 9am.  Firstly this will cache all the other objects on the site, so you won’t have to load them all when the site is particularly busy.  Secondly, you will be in line in case they open the booking early (which has been known to happen).
  • Give your reg numbers to other friends who are trying to book tickets.  Your chances are better, and in the past it warned you if a ticket had already been booked for a number, so you couldn’t buy them twice.
  • Stay calm, and keep trying.  Quite often you can get lucky, hit a lull in traffic and get your booking in quick and easily.
  • A few more tabs when refreshing is fine, but bear in mind your session may be shared amongst them, so you may have issues if trying to fill out the forms in multiple tabs at the same time.  It’s best to try to follow the forms through on one tab before you try the same on another (where you are trying to book more than 6 tickets).

Finally, for redundancy and to increase your chances, have several computers available.  An OS crash could kill your chances of getting tickets, you can also refresh quicker and hit the servers faster with two endpoints rather than one.

A neat trick that worked well last year, because of a dodgy DNS record, was to add the server address to your OS hosts file.  This saves the browser needing to do a DNS lookup to find the address, which could save time every minute or so, as the time-to-live record is set so low.  I’d not recommend doing this when using one computer, unless on the day it becomes clear that one of the IP addresses is down.  You stand the best chance if you can hit any of the servers.

With several computers though, perhaps it’s worth setting a DNS record in each hosts file.  In windows, this file is located in c:\windows\system32\drivers\etc usually.  You need to open it as administrator, and add a line, something like the following to it:

194.168.202.202 glastonbury.seetickets.com

You have to open notepad as administrator to edit this file.

I decided to take a mixed approach – use one computer with a fixed host record, and the other doing normal DNS lookups.  This would allow flexibility – I can use one to change the IP manually if necessary, and hit all possible servers on the other.

Ok, so we are just about ready.  Now, just time to check the Firefox extension is working ok, and we are ready to go!

9 thoughts on “Examining the Glastonbury Ticket Sales Website

    1. Hi Lewis, hope you managed to get tickets last year/this year. I’ve noticed a few things that have changed this year, I’ll see if I can come up with an updated post soon. Won’t be quite as detailed, but does appear they are now using IP rate limiting (hence the advice to only use one device at once).

      1. Hi Chris, doing some prep for 2020 already haha – how did you find out they are rate limiting by the way?

      2. I don’t remember what analysis I did, but there was a post from Emily Eavis implying that mutliple tabs and browser windows would cause problems last time around. We also found that multiple computers on the same IP was getting much less good results than using phones on 4G, and connecting to a VPN. I didn’t make as big of an effort though last October, so I didn’t do much analysis on what was happening. I failed to purchase the tickets twice after putting card details in, which hasn’t happened to me on previous years.

  1. Thanks very much for the information about the ‘Check4Change’ plugin. With six computers running Firefox and with the refresh set to 2 seconds, I was able to order Glastonbury tickets for my sister. I also installed another plugin called ‘ImageBlock’ to stop images loading although I’m not sure if this helped or not.

    1. Glad to hear it Matt! I didn’t have the chance to update the post for this year as I was out of town. But the technology and queuing system was slightly enhanced last year. It makes it more difficult to purchase more than 6 tickets, though I am glad to check4change plugin is still useful!

  2. It seems that its all changed this year… Apparently they have new servers. I tried ping, and it seems they have blocked this function now.

    After sitting back and looking over my actions from this morning, the only way I can see anyone having a better chance is to use something like Google Chrome with a few windows open in incognito mode, with a plugin like Refresh Monkey running every 5 seconds on all windows pointing to the following url “http://glastonbury.seetickets.com/event/glastonbury-2017-deposits/worthy-farm/1100000/” and have the mode set to “Stop refresh when URL changes” – this would mean it would stop the page when it loads into the application / payment window, as once you are in, you have a session saved on the server for you to fill in your details.

    After reading up on Twitter and Facebook on what people did to get their tickets, it seems waiting the 20 seconds is pointless, as people were hitting the refresh button every 5 seconds regardless if they had a page display on their screen. I seemed to have failed by waiting for a timeout or anything to happen when trying to get tickets this morning.

    I’ve even took up writing a little Applescript that will check the URL every 3 seconds to see if it gets a connection, if not, it will try again till it can receive a connection and open up the URL once it does… might give this a try this next time around to see if I can get a ticket, along with using the above method… fingers crossed.

    1. Can you tell I’ve been bored today, and done some research into a bit more of this now, and have more questions then answers haha… Anyway, so as with most popular websites, they use load balancing, so See Tickets have a number of servers. On your first visit, you are directed to a server behind the load balancer and are set an X-Mapping-XXXXXXXX cookie with a string of encrypted code (this will be your session ID on the server behind the load balancer), and the XXXX’s are probably the load balances identity code – you will notice these below.

      Anyway, the question now is, would it be better to get a new ID each time you refresh your browser, in theory pointing to another server behind the load balancer, would that give you more chance of getting a website to display?

      So for example, If I cURL the URL from within Terminal, I get a different server every time:
      1. Set-Cookie: X-Mapping-kgibjjhc=78CEF00D91D78687A41C9C2369AE1755; path=/
      2. Set-Cookie: X-Mapping-kgibjjhc=DBADD375D5D3EAE853E0A2FECAC0F77E; path=/
      3. Set-Cookie: X-Mapping-kgibjjhc=52F6FBC54C65511FB7F38FB2D142FED1; path=/
      4. Set-Cookie: X-Mapping-kgibjjhc=D99C5766EC99492734EE6A5E86FDE251; path=/
      5. Set-Cookie: X-Mapping-kgibjjhc=F52A55C3DF592650DA48FE55FCF3E5AE; path=/
      6. Set-Cookie: X-Mapping-kgibjjhc=F52A55C3DF592650DA48FE55FCF3E5AE; path=/
      7. Set-Cookie: X-Mapping-kgibjjhc=2A017EE24B74BB0AFB714CC687CA23AB; path=/
      8. Set-Cookie: X-Mapping-kgibjjhc=AA05972B9548CFFA739C04F521677B59; path=/
      9. Set-Cookie: X-Mapping-kgibjjhc=1EF073EF63C31B3E935A08684E5406F2; path=/
      10. Set-Cookie: X-Mapping-kgibjjhc=C08E1BD6F1BB00CF0844CF2DA5EEAF68; path=/
      11. Set-Cookie: X-Mapping-kgibjjhc=AA05972B9548CFFA739C04F521677B59; path=/
      12. Set-Cookie: X-Mapping-kgibjjhc=C08E1BD6F1BB00CF0844CF2DA5EEAF68; path=/

      That is just a few, but you will notice some duplicates (where i was sent to the same server behind the load balancer, for instance post 5&6, 10&12 and 8&11….)

      So in my little script, I get it to open a new incognito window once its received a connection, and it will open up to 9 windows every 3 seconds… I noticed that once a cookie is set (even on incognito), i will be redirected to that very same server from my initial visit… Is this a good thing? Or a bad thing?

      Now I can code in and grab that cookie above and send that to Chrome once each window opens…. That would mean I could have a window session for each server behind the load balancer…. would that give me more chance, or would there be more chance on concentrating on a single server?

      1. Great work James. I think you’d have more chance distributing your requests across all servers, since it’s likely one or more will go down or be too busy. That could also be why a lot of requests were failing to connect at all (the server the cookie was directing to was unable to handle the traffic).

        However, if they are using IP rate limiting, that would mean only a certain number of your requests would be allowed to connect to the load balancer at all (probably Stingray traffic manager I think).

        A way around this would be multiple devices using VPN tunnels via Tor or providers like ExpressVPN or VanishIP. That would give each device a different originating address so would work around any IP rate limits too. You could have each device hitting a different server through your script.

        Once you do get in the queue and are redirected to a new URL, you want to keep using the same cookie – that’s what decides whether you are allowed to progress to registration or not, and gives you a limited time to do it before you are thrown back in the main queue again.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s