Managing Cold Start On Google App Engine

One of the major problem working on Google App engine is managing cold start. Well what is it?

Google App engine spins down the application when it is idle. On Google App engine, application does not get a permanent instance of java virtual machine. If there are no activities for a while then the JVM goes cold and application will have to start again to render a request. This is cold start and your application will be sluggish if you render a request to it after a while.

GAE team has accepted the issue and introduced “Ability to reserve instances to reduce application loading overhead” into their roadmap.

This is an issue we traditionally are not aware about while developing an application on Google App engine. If we are working on a greenfield project and we have a liberty of choosing the frameworks then we can stay away from heavy frameworks.

The application we are porting is Spring/Wicket/JPA tehnology stack and we like others were suffering from cold start. When the application warms up all the Spring beans are initialized again. Since we use JPA the EntityManagerFactory adds a significant amount of time for startup.

The quick fix for the cold start till Google App engine team figures it out, is to ping the application every few minutes. This will keep the application from going into the cold storage.

For this implementation to work we require a Servlet which essentially does nothing apart from receiving the request. We also require a cron job which renders request every few minutes. Let’s look at the servlet code listing and its mapping in web.xml.

[sourcecode language=”java”]
public class PingServlet extends HttpServlet {

private Logger logger = Logger.getLogger(PingServlet.class);

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
logger.info("Keeping the application warm");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
[/sourcecode]

[sourcecode language=”xml”]
. . .
<servlet>
<display-name>PingServlet</display-name>
<servlet-name>PingServlet</servlet-name>
<servlet-class>com.bookmyhours.init.PingServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>PingServlet</servlet-name>
<url-pattern>/ping.html</url-pattern>
</servlet-mapping>
. . .
[/sourcecode]

We need to create a cron job descriptor by the name cron.xml and place it inside WEB-INF folder in the application. This file needs a servlet url it needs to hit and the schedule information. You can read more about cron jobs here. The code listing for cron.xml.

[sourcecode language=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/ping.html</url>
<description>Ping a blank page</description>
<schedule>every 5 minutes</schedule>
</cron>
</cronentries>
[/sourcecode]

There are other different strategies you may follow. For Spring we need to figure out which beans can be lazily loaded so that whenever the application comes to life after a cold start number of beans being initialized can be reduced.

If you are working on a green field project and have liberty of choosing frameworks then the persistence framework can be low level datastore to avoid the EntityManagerFactory overhead or use other persistence frameworks like objectify.

4 thoughts on “Managing Cold Start On Google App Engine

  1. Hello Meetu,

    I believe this is not an ideal solution. 5 minutes is waaay too long in between pings, the VMs go down after a minute already, you can see it happen in the new Instance View. And why are they shut down so eagerly? Because people ping them so frequently and consume resources.. A vicious cycle! 🙂 (I believe the official policy even disallows pinging)

    There are many other suggestions out there, many of those even allow you to keep your framework of choice. I’ve also written a post on it recently, and since you’re using Wicket just like me, you may want to have a look.

    http://www.small-improvements.com/app-engine-loading-request-performance

    Cheers,
    Per

    1. Hi Per,
      Sure this is not an ideal solution and yes 5 minutes is indeed too less, it is 1 minute now. As I mentioned in the post this should be seen as a workaround or a quick fix for an existing project. We have seen endless discussion on GAE forums for and against this solution and my take on this is to wait and watch and let google come up with an ideal solution. It will be sad that due to GAE limitations certain frameworks like spring and others be branded unusable on GAE. I like Wicket framework too, I will have a look at your post and see what can I incorporate in my project.
      Cheers,
      Meetu

  2. The release 1.4.0 for GAE includes the feature “Always On”. With this you can pay ($0.30/day) to reserve 3 instances for your application. These instances will not spin down.

    This is very usefull for applications that have a very low request rate, but applications which are hit by a burst of request will still suffer from startup problems for instance 4 and higher.

Leave a Reply

%d bloggers like this: