             opts.query += " LIMIT #{opts.limit} "
 
         dbg("query='#{opts.query}'")
+        if opts.cache and @_query_cache?
+            # check for cached result
+            full_query_string = JSON.stringify([opts.query, opts.params])
+            if (x = @_query_cache.get(full_query_string))?
+                dbg("using cache for '#{opts.query}'")
+                opts.cb?(x...)
+                return
 
         # params can easily be huge, e.g., a blob.  But this may be
         # needed at some point for debugging.

class exports.PostgreSQL extends EventEmitter    # emits a 'connect' event whenever we successfully connect to the database.
    constructor: (opts) ->
        opts = defaults opts,
            host     : process.env['SMC_DB_HOST'] ? 'localhost'    # or 'hostname:port'
            database : process.env['SMC_DB'] ? 'smc'
            debug    : true
            connect  : true
        @setMaxListeners(10000)  # because of a potentially large number of changefeeds
        @_state = 'init'
        @_debug = opts.debug

            @_port = 5432
        @_database = opts.database
        @_concurrent_queries = 0
        if opts.cache_expiry and opts.cache_size
            @_query_cache = (new require('expiring-lru-cache'))(size:opts.cache_size, expiry: opts.cache_expiry)
        if opts.connect
            @connect()  # start trying to connect

