Hi Eric, Thanks for the quick reply. Java lib version is 0.04, server version is 0.11 if that matters. here is the client code, the handle function is called for each http request, and it submits a job to gearmand. below is also the connection pool class (maintains live clients and hand them over to threads). The problems only appears when I many active clients. I am testing with 'siege' which is a simple http stress tester. I see problems at 100 or more concurrent clients (there are enough workers to handle this load, spread across 16 machines). static class CropHandler implements Handler { private final GearmanConnectionPool m_gcp; public CropHandler(GearmanConnectionPool gcp) { m_gcp = gcp; } @Override public void handle(String target, HttpServletRequest request, HttpServletResponse response) throws Exception { String url = request.getParameter("url"); int x = Util.toInt(request.getParameter("x"), 0); int y = Util.toInt(request.getParameter("y"), 0); int w = Util.toInt(request.getParameter("width"), 0); int h = Util.toInt(request.getParameter("height"), 0); CropResponse res = null; for(int i=0;i<3;i++) { GearmanClient gc = null; try { gc = m_gcp.get(); res = getResponse(url, x, y, w, h, gc); break; } catch(RejectedExecutionException e1) { logger.warn("IOException getting crop_image response, retry ("+i+")" + e1.getMessage()); gc.shutdown(); gc = null; } catch(IOException e) { logger.warn("IOException getting crop_image response, retry ("+i+")" + e.getMessage()); gc.shutdownNow(); gc = null; } finally { if (gc != null) m_gcp.release(gc); } } if (res == null) { String msg = "Failed to obtain crop_image response"; logger.warn(msg); response.sendError(500, msg); } else { if (res.hasError()) { String msg = res.getError().getType() + " : " + res.getError().getMessage(); logger.warn(msg); response.sendError(500, msg); } else { response.setContentType("image/jpeg"); response.getOutputStream().write(res.getImage().toByteArray()); } } ((Request) request).setHandled(true); } private CropResponse getResponse(String url, int x, int y, int w, int h, GearmanClient gc) throws InvalidProtocolBufferException, IOException, InterruptedException, ExecutionException { CropRequest req = CropRequest.newBuilder().setUrl(url).setTopX(x).setTopY(y).setWidth(w).setHeight(h).build(); long t = System.currentTimeMillis(); CropResponse res = CropResponse.parseFrom(sendRequest(gc, req, "crop_image")); long e = System.currentTimeMillis() - t; int cropTimeMs = res.getCropTimeMs(); int downloadTimeMs = res.getDownloadTimeMs(); logger.debug("Total time " + e + ", download " + downloadTimeMs + ", crop " + cropTimeMs + ", overhead " + (e - res.getTotalTimeMs())); return res; } } public class GearmanConnectionPool { private List m_servers; Queue m_available = new LinkedList(); public void init(List servers) { m_servers = servers; } public synchronized GearmanClient get() { if (m_available.size() > 0) { return m_available.remove(); } else { GearmanClient client = new GearmanClientImpl(); for(Swush g : m_servers) { client.addJobServer(new GearmanNIOJobServerConnection(g.selectProperty("gearman.host") , g.selectIntProperty("gearman.port", 4730))); } return client; } } public synchronized void release(GearmanClient gc) { m_available.add(gc); // gc.shutdown(); } }