Run Slow

(click to open)

Quick Page Table of Contents


My PHP web too slow

There are many ways to set your Zend Server site for performance problems. The following non-optimal choices are intended to assist through experience, any resemblance to existing IBM i sites is purely coincidental ( .

These ideas are only shotgun style scenarios that may or may not help you fix a specific issue. I recommend that you attend a performance data gathering session like Alan’s eLearning course ( or full-day ZendCon tutorial (

IFS: I use PHP session data, site slows for no reason (/tmp/sessxxxxx).

  • Problem: Constant writes to IFS of PHP session data can stall site requests up to 30 seconds or more.
  • Solution: {PHP DB2 session} - replace PHP sessions with DB2 session support (example)
  • Alternative:
    • [Session]                                        
      ; Handler used to store/retrieve data.           
      session.save_path = "/tmp/sessionfiles" ; default is actually /tmp
      ;To use sqlite, change it to:
      session.save_handler = sqlite
      session.save_path = "/path/sessions.db"

XMLSERVICE: I need *LIBL, so i use private connection and disconnect (internalKey=‘/tmp/fred42′).

  • Problem: Constant start/stop XMLSERVICE private jobs too slow and resource intense.
  • Solution: If simple LIBL issue, try “stateless” profile with INLLIBL(MY LIB LIST HERE)
                 INLPGM(IWEBDEMO/INLPGM) TEXT('For IWEBDEMO application') +
  • Alternative: If you need more than *LIBL each xmlservice private connection, consider pooling your connections.
    • Example below sets 10 connections /tmp/packers1 - 10 for use with this user profile.
    • <?php
      try { $ToolkitServiceObj = ToolkitService::getInstance($db, $user, $pass, $extension); }
      catch (Exception $e) { echo  $e->getMessage(), "\n"; exit(); }  
      $maxpool = 10; // 10 jobs good enough to handle my machine needs 
      $internalKey = '/tmp/packers'.rand(1,$maxpool); 
      /* Do not use the disconnect() function for "state full" connection */ 
      /* NEVER EVER USE THIS ... $ToolkitServiceObj->disconnect();        */ 
      /* Why? *immed kill of job, not nice or sync, just kill             */ 
    • You may want to consider prestarting XMLSERVICE jobs if you have peak demand issues

XMLSERVICE: I call *PGM/*SRVPGMs that cause inquiry messages to QSYSOPR.

  • Problem: Called programs inquiry messages to QSYSOPR hang php-cgi jobs (QSQSRVR)
  • Solution: Use idle timeout support in PHP Toolkit to abandon hung program
    • // let's assume the toolkit connection has been established using getInstance() and is present in the variable $conn:
      $idleTimeoutSeconds = 20; // 20 second timeout; a value of 0 means no timeout (infinite wait)
      $conn->setOptions(array('idleTimeout' => $idleTimeoutSeconds));

PHP: I have peak demand at 8am, PHP is just too slow.

  • Problem: Everyone looks at home page at 8am and sinks my site with php requests.
  • Solution: Make first page pure html (no PHP) … with interesting info worth reading in the morning
    • Note: Often times simply PHP generating home page as pure html night before will fix everything (hey even database data rarely has to be that up to date before people have thier second cup of coffee)

ibm_db2: I can’t use db2_pconnect, because QSQSRVR jobs die (or operator kill).

  • Problem: Unreliable persistent QSQSRVR connections cause many issues.
  • Solution: Use a db2 maid service for your persistent connections
    • // check ok connection with db2 maid service
      for ($i=0;$i<2;$i++) {
       $conn = db2_pconnect($db,$uid,$pwd,$options);
       if (!$conn) die("Bad connection due to profile ($db, $uid)");
       // Note: V7+ system naming will accept both '.' and '/' (yahoo)
       //       V6 has PTFs for this same function             (cool)
       //       V5 you are stuck forever in '.' or '/' limbo   (yuck)
       $maid = db2_exec($conn, 'SELECT CURRENT DATE FROM SYSIBM.SYSDUMMY1'); // try sql naming
       if (!$maid) $maid = db2_exec($conn, 'SELECT CURRENT DATE FROM SYSIBM/SYSDUMMY1'); // try system naming
       if (!$maid) db2_pclose($conn); // simple test failed close connection for re-connect
       if ($i>0 && !$maid) die("Bad connection no idea what is wrong (see operator)."); // internal error
      // db2 maid service says persistent connection working, so on with the real work ...

ibm_db2: QTEMP issue with i5_libl => “QTEMP FRED”

  • Problem: Error exists in ibm_db2 driver setting CURLIB to QTEMP
  • Solution: Use you own version of i5_libl and i5_curlib
    • $naming = array("i5_naming"=>DB2_I5_NAMING_ON);
      $conn = db2_connect("*LOCAL","DRAMA","GUY",$naming);
      $chglibl = "CHGLIBL LIBL(QTEMP FRED)";
      $sobig1 = strlen($chglibl);
      $sql1 = "CALL QSYS2/QCMDEXC('$chglibl',$sobig1)";
      $ret = db2_exec($conn,$sql1);
      $chgcurlib = "CHGCURLIB CURLIB(FRED)";
      $sobig2 = strlen($chgcurlib);
      $sql2 = "CALL QSYS2/QCMDEXC('$chgcurlib',$sobig2)";
      $ret = db2_exec($conn,$sql2);

Hardware: My web site is running on 1/10 of a processor.

  • Problem: Running with less CPU than average cell phone.
  • Solution: Add minimum one full processor to get powerpc real benefits.