ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://www.php.net/manual/en/features.persistent-connections.php |
| Last Crawled | 2026-04-16 17:52:40 (13 hours ago) |
| First Indexed | 2019-03-25 16:14:43 (7 years ago) |
| HTTP Status Code | 200 |
| Meta Title | PHP: Persistent Database Connections - Manual |
| Meta Description | Persistent Database Connections |
| Meta Canonical | null |
| Boilerpipe Text | What are Persistent Connections?
Persistent connections are links that do not close when the
execution of your script ends. When a persistent connection is
requested, PHP checks if there's already an identical persistent
connection (that remained open from earlier) - and if it exists, it
uses it. If it does not exist, it creates the link. An 'identical'
connection is a connection that was opened to the same host, with
the same username and the same password (where applicable).
There's no method of requesting a specific connection, or guaranteeing
whether you get an existing connection or a brand new one (if all existing
connections are in use, or the request is being served by a different worker,
which has a separate pool of connections).
This means that you cannot use PHP's persistent connections to, for example:
assign a specific database session to a specific web user
create a large transaction across multiple requests
initiate a query on one request and collect the results on another
Persistent connections do not give you
any
functionality that wasn't possible with non-persistent connections.
Web Requests
There are two ways in which your web server can utilize PHP to generate
web pages:
The first method is to use PHP as a CGI "wrapper". When run this
way, an instance of the PHP interpreter is created and destroyed
for every page request (for a PHP page) to your web server.
Because it is destroyed after every request, any resources that it
acquires (such as a link to an SQL database server) are closed when
it is destroyed. In this case, you do not gain anything from trying
to use persistent connections - they simply don't persist.
The second, and most popular, method is to run PHP-FPM, or PHP as a module
in a multiprocess web server, which currently only includes Apache.
These setups typically have one process (the parent) which
coordinates a set of processes (its children) who actually do the
work of serving up web pages. When a request comes in from a
client, it is handed off to one of the children that is not already
serving another client. This means that when the same client makes
a second request to the server, it may be served by a different
child process than the first time. When opening a persistent connection,
every following page requesting SQL services can reuse the same
established connection to the SQL server.
Note
:
You can check which method your web requests use by checking the value of
"Server API" in the output of
phpinfo()
or the value of
PHP_SAPI
, run from a web request.
If the Server API is "Apache 2 Handler" or "FPM/FastCGI", then persistent
connections will be used across requests served by the same worker. For any
other value, persistent connections will not persist after each request.
Command-line Processes
As command-line PHP uses a new process for each script, persistent
connections are not shared between command-line scripts, so there is no
value in using them in transient scripts such as crons or commands.
However, they may be useful if, for example, you're writing a long-running
application server that serves many requests or tasks and each may need
their own database connection.
Why Use Them?
Persistent connections are good if the overhead to create a link to your
SQL server is high. Whether or not this overhead is really high depends
on many factors. Like, what kind of database it is, whether or not
it sits on the same computer on which your web server sits, how
loaded the machine the SQL server sits on is and so forth. The
bottom line is that if that connection overhead is high, persistent
connections help you considerably. They cause the child process to
simply connect only once for its entire lifespan, instead of every
time it processes a page that requires connecting to the SQL
server. This means that for every child that opened a persistent
connection will have its own open persistent connection to the
server. For example, if you had 20 different child processes that
ran a script that made a persistent connection to your SQL server,
you'd have 20 different connections to the SQL server, one from
each child.
Potential Drawbacks: Connection Limits
Note, however, that this can have some drawbacks if you are using a
database with connection limits that are exceeded by persistent
child connections. If your database has a limit of 16 simultaneous
connections, and in the course of a busy server session, 17 child
threads attempt to connect, one will not be able to. If there are
bugs in your scripts which do not allow the connections to shut
down (such as infinite loops), the database with only 16 connections
may be rapidly swamped.
Persistent connections will usually increase the number of connections open
at any given time because idle workers will still hold the connections for
the previous requests they served. If a large number of workers is spun up to
handle an influx of requests, the connections they opened will remain until
the worker is killed or the database server closes the connection.
Ensure that the maximum number of connections allowed by the database server
is greater than the maximum number of web request workers (plus any other
usage such as crons or administrative connections).
Check your database documentation for information on handling abandoned or
idle connections (timeouts). Long timeouts may significantly increase the
number of persistent connections open at any one time.
Potential Drawbacks: Maintaining Connection State
Some database extensions perform automatic cleanup when the connection is
reused; others leave this task at the discretion of the application developer.
Depending on the chosen database extension and the application design, manual
cleanup may be needed before the script exits. Changes that may leave
connections in an unexpected state include:
Selected / default database
Table locks
Uncommitted transactions
Temporary tables
Connection specific settings or features such as profiling
Table locks and transactions that are not cleaned up or closed may cause
other queries to be blocked indefinitely and/or cause subsequent reuse of
the connection to cause unexpected changes.
Having the wrong database selected will cause subsequent reuse of the
connection to be unable to execute queries as expected (or execute them on
the wrong database if schemas are similar enough).
If temporary tables are not cleaned up, subsequent requests will not be able
to recreate the same table.
You can implement cleanup using class destructors or
register_shutdown_function()
. You may also want to
consider dedicated connection pooling proxies that include this as part of
their functionality.
Final Words
Given their behavior and potential drawbacks described above, you should not
use persistent connections without careful consideration. They should not be
used without implementing additional changes to your application and careful
configuration of your database server and web server and/or PHP-FPM.
Consider alternative solutions such as investigating and fixing the causes of
connection creation overheads (for example, disabling reverse DNS lookups on
the database server), or dedicated connection pooling proxies.
For high volume web APIs, consider using alternative runtimes or long-running
application servers.
See Also
ibase_pconnect()
oci_pconnect()
odbc_pconnect()
pfsockopen()
pg_connect()
MySQLi and Persistent Connections
PDO Connection Management
22
Tom
¶
16 years ago
There's a third case for PHP: run on a fastCGI interface. In this case, PHP processes are NOT destroyed after each request, and so persistent connections do persist. Set PHP_FCGI_CHILDREN << mysql's max_connections and you'll be fine.
14
ambrish at php dot net
¶
15 years ago
In IBM_DB2 extension v1.9.0 or later performs a transaction rollback on persistent connections at the end of a request, thus ending the transaction. This prevents the transaction block from carrying over to the next request which uses that connection if script execution ends before the transaction block does.
14
php at alfadog dot net
¶
12 years ago
One additional not regarding odbc_pconnect and possibly other variations of pconnect:
If the connection encounters an error (bad SQL, incorrect request, etc), that error will return with be present in odbc_errormsg for every subsequent action on that connection, even if subsequent actions don't cause another error.
For example:
A script connects with odbc_pconnect.
The connection is created on it's first use.
The script calls a query "Select * FROM Table1".
Table1 doesn't exist and odbc_errormsg contains that error.
Later(days, perhaps), a different script is called using the same parameters to odbc_pconnect.
The connection already exists, to it is reused.
The script calls a query "Select * FROM Table0".
The query runs fine, but odbc_errormsg still returns the error about Table1 not existing.
I'm not seeing a way to clear that error using odbc_ functions, so keep your eyes open for this gotcha or use odbc_connect instead.
14
christopher dot jones at oracle dot com
¶
18 years ago
For the oci8 extension it is not true that " [...] when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does.". The oci8 extension does a rollback at the end scripts using persistent connections, thus ending the transaction. The rollback also releases locks. However any ALTER SESSION command (e.g. changing the date format) on a persistent connection will be retained over to the next script.
11
ynzhang from lakeheadu canada
¶
17 years ago
It seems that using pg_pconnect() will not persist the temporary views/tables. So if you are trying to create temporary views/tables with the query results and then access them with the next script of the same session, you are out of luck. Those temporary view/tables are gone after each PHP script ended. One way to get around this problem is to create real view/table with session ID as part of the name and record the name&creation time in a common table. Have a garbage collection script to drop the view/table who's session is expired.
10
jean_christian at myrealbox dot com
¶
23 years ago
If anyone ever wonders why the number of idle db process (open connections) seems to grow even though you are using persistent connections, here's why:
"You are probably using a multi-process web server such as Apache. Since
database connections cannot be shared among different processes a new
one is created if the request happen to come to a different web server
child process."
8
andy at paradigm-reborn dot com
¶
19 years ago
To those using MySQL and finding a lot of leftover sleeping processes, take a look at MySQL's wait_timeout directive. By default it is set to 8 hours, but almost any decent production server will have been lowered to the 60 second range. Even on my testing server, I was having problems with too many connections from leftover persistent connections. |
| Markdown | [update page now](https://www.php.net/x-myracloud-5958a2bbbed300a9b9ac631223924e0b/1776361960.371)
[](https://www.php.net/)
- [Downloads](https://www.php.net/downloads.php)
- [Documentation](https://www.php.net/docs.php)
- [Get Involved](https://www.php.net/get-involved.php)
- [Help](https://www.php.net/support.php)
- [](https://www.php.net/releases/8.5/index.php)
Search docs
[Getting Started](https://www.php.net/manual/en/getting-started.php)
[Introduction](https://www.php.net/manual/en/introduction.php)
[A simple tutorial](https://www.php.net/manual/en/tutorial.php)
[Language Reference](https://www.php.net/manual/en/langref.php)
[Basic syntax](https://www.php.net/manual/en/language.basic-syntax.php)
[Types](https://www.php.net/manual/en/language.types.php)
[Variables](https://www.php.net/manual/en/language.variables.php)
[Constants](https://www.php.net/manual/en/language.constants.php)
[Expressions](https://www.php.net/manual/en/language.expressions.php)
[Operators](https://www.php.net/manual/en/language.operators.php)
[Control Structures](https://www.php.net/manual/en/language.control-structures.php)
[Functions](https://www.php.net/manual/en/language.functions.php)
[Classes and Objects](https://www.php.net/manual/en/language.oop5.php)
[Namespaces](https://www.php.net/manual/en/language.namespaces.php)
[Enumerations](https://www.php.net/manual/en/language.enumerations.php)
[Errors](https://www.php.net/manual/en/language.errors.php)
[Exceptions](https://www.php.net/manual/en/language.exceptions.php)
[Fibers](https://www.php.net/manual/en/language.fibers.php)
[Generators](https://www.php.net/manual/en/language.generators.php)
[Attributes](https://www.php.net/manual/en/language.attributes.php)
[References Explained](https://www.php.net/manual/en/language.references.php)
[Predefined Variables](https://www.php.net/manual/en/reserved.variables.php)
[Predefined Exceptions](https://www.php.net/manual/en/reserved.exceptions.php)
[Predefined Interfaces and Classes](https://www.php.net/manual/en/reserved.interfaces.php)
[Predefined Attributes](https://www.php.net/manual/en/reserved.attributes.php)
[Context options and parameters](https://www.php.net/manual/en/context.php)
[Supported Protocols and Wrappers](https://www.php.net/manual/en/wrappers.php)
[Security](https://www.php.net/manual/en/security.php)
[Introduction](https://www.php.net/manual/en/security.intro.php)
[General considerations](https://www.php.net/manual/en/security.general.php)
[Installed as CGI binary](https://www.php.net/manual/en/security.cgi-bin.php)
[Installed as an Apache module](https://www.php.net/manual/en/security.apache.php)
[Session Security](https://www.php.net/manual/en/security.sessions.php)
[Filesystem Security](https://www.php.net/manual/en/security.filesystem.php)
[Database Security](https://www.php.net/manual/en/security.database.php)
[Error Reporting](https://www.php.net/manual/en/security.errors.php)
[User Submitted Data](https://www.php.net/manual/en/security.variables.php)
[Hiding PHP](https://www.php.net/manual/en/security.hiding.php)
[Keeping Current](https://www.php.net/manual/en/security.current.php)
[Features](https://www.php.net/manual/en/features.php)
[HTTP authentication with PHP](https://www.php.net/manual/en/features.http-auth.php)
[Cookies](https://www.php.net/manual/en/features.cookies.php)
[Sessions](https://www.php.net/manual/en/features.sessions.php)
[Handling file uploads](https://www.php.net/manual/en/features.file-upload.php)
[Using remote files](https://www.php.net/manual/en/features.remote-files.php)
[Connection handling](https://www.php.net/manual/en/features.connection-handling.php)
[Persistent Database Connections](https://www.php.net/manual/en/features.persistent-connections.php)
[Command line usage](https://www.php.net/manual/en/features.commandline.php)
[Garbage Collection](https://www.php.net/manual/en/features.gc.php)
[DTrace Dynamic Tracing](https://www.php.net/manual/en/features.dtrace.php)
[Function Reference](https://www.php.net/manual/en/funcref.php)
[Affecting PHP's Behaviour](https://www.php.net/manual/en/refs.basic.php.php)
[Audio Formats Manipulation](https://www.php.net/manual/en/refs.utilspec.audio.php)
[Authentication Services](https://www.php.net/manual/en/refs.remote.auth.php)
[Command Line Specific Extensions](https://www.php.net/manual/en/refs.utilspec.cmdline.php)
[Compression and Archive Extensions](https://www.php.net/manual/en/refs.compression.php)
[Cryptography Extensions](https://www.php.net/manual/en/refs.crypto.php)
[Database Extensions](https://www.php.net/manual/en/refs.database.php)
[Date and Time Related Extensions](https://www.php.net/manual/en/refs.calendar.php)
[File System Related Extensions](https://www.php.net/manual/en/refs.fileprocess.file.php)
[Human Language and Character Encoding Support](https://www.php.net/manual/en/refs.international.php)
[Image Processing and Generation](https://www.php.net/manual/en/refs.utilspec.image.php)
[Mail Related Extensions](https://www.php.net/manual/en/refs.remote.mail.php)
[Mathematical Extensions](https://www.php.net/manual/en/refs.math.php)
[Non-Text MIME Output](https://www.php.net/manual/en/refs.utilspec.nontext.php)
[Process Control Extensions](https://www.php.net/manual/en/refs.fileprocess.process.php)
[Other Basic Extensions](https://www.php.net/manual/en/refs.basic.other.php)
[Other Services](https://www.php.net/manual/en/refs.remote.other.php)
[Search Engine Extensions](https://www.php.net/manual/en/refs.search.php)
[Server Specific Extensions](https://www.php.net/manual/en/refs.utilspec.server.php)
[Session Extensions](https://www.php.net/manual/en/refs.basic.session.php)
[Text Processing](https://www.php.net/manual/en/refs.basic.text.php)
[Variable and Type Related Extensions](https://www.php.net/manual/en/refs.basic.vartype.php)
[Web Services](https://www.php.net/manual/en/refs.webservice.php)
[Windows Only Extensions](https://www.php.net/manual/en/refs.utilspec.windows.php)
[XML Manipulation](https://www.php.net/manual/en/refs.xml.php)
[GUI Extensions](https://www.php.net/manual/en/refs.ui.php)
Keyboard Shortcuts
?
This help
j
Next menu item
k
Previous menu item
g p
Previous man page
g n
Next man page
G
Scroll to bottom
g g
Scroll to top
g h
Goto homepage
g s
Goto search
(current page)
/
Focus search box
[Command line usage »](https://www.php.net/manual/en/features.commandline.php)
[« Connection handling](https://www.php.net/manual/en/features.connection-handling.php)
- [Preface](https://www.php.net/manual/en/index.php)
- [Features](https://www.php.net/manual/en/features.php)
# Persistent Database Connections
### What are Persistent Connections?
Persistent connections are links that do not close when the execution of your script ends. When a persistent connection is requested, PHP checks if there's already an identical persistent connection (that remained open from earlier) - and if it exists, it uses it. If it does not exist, it creates the link. An 'identical' connection is a connection that was opened to the same host, with the same username and the same password (where applicable).
There's no method of requesting a specific connection, or guaranteeing whether you get an existing connection or a brand new one (if all existing connections are in use, or the request is being served by a different worker, which has a separate pool of connections).
This means that you cannot use PHP's persistent connections to, for example:
- assign a specific database session to a specific web user
- create a large transaction across multiple requests
- initiate a query on one request and collect the results on another
Persistent connections do not give you *any* functionality that wasn't possible with non-persistent connections.
### Web Requests
There are two ways in which your web server can utilize PHP to generate web pages:
The first method is to use PHP as a CGI "wrapper". When run this way, an instance of the PHP interpreter is created and destroyed for every page request (for a PHP page) to your web server. Because it is destroyed after every request, any resources that it acquires (such as a link to an SQL database server) are closed when it is destroyed. In this case, you do not gain anything from trying to use persistent connections - they simply don't persist.
The second, and most popular, method is to run PHP-FPM, or PHP as a module in a multiprocess web server, which currently only includes Apache. These setups typically have one process (the parent) which coordinates a set of processes (its children) who actually do the work of serving up web pages. When a request comes in from a client, it is handed off to one of the children that is not already serving another client. This means that when the same client makes a second request to the server, it may be served by a different child process than the first time. When opening a persistent connection, every following page requesting SQL services can reuse the same established connection to the SQL server.
> **Note**:
>
> You can check which method your web requests use by checking the value of "Server API" in the output of [phpinfo()](https://www.php.net/manual/en/function.phpinfo.php) or the value of **`PHP_SAPI`**, run from a web request.
>
> If the Server API is "Apache 2 Handler" or "FPM/FastCGI", then persistent connections will be used across requests served by the same worker. For any other value, persistent connections will not persist after each request.
### Command-line Processes
As command-line PHP uses a new process for each script, persistent connections are not shared between command-line scripts, so there is no value in using them in transient scripts such as crons or commands. However, they may be useful if, for example, you're writing a long-running application server that serves many requests or tasks and each may need their own database connection.
### Why Use Them?
Persistent connections are good if the overhead to create a link to your SQL server is high. Whether or not this overhead is really high depends on many factors. Like, what kind of database it is, whether or not it sits on the same computer on which your web server sits, how loaded the machine the SQL server sits on is and so forth. The bottom line is that if that connection overhead is high, persistent connections help you considerably. They cause the child process to simply connect only once for its entire lifespan, instead of every time it processes a page that requires connecting to the SQL server. This means that for every child that opened a persistent connection will have its own open persistent connection to the server. For example, if you had 20 different child processes that ran a script that made a persistent connection to your SQL server, you'd have 20 different connections to the SQL server, one from each child.
### Potential Drawbacks: Connection Limits
Note, however, that this can have some drawbacks if you are using a database with connection limits that are exceeded by persistent child connections. If your database has a limit of 16 simultaneous connections, and in the course of a busy server session, 17 child threads attempt to connect, one will not be able to. If there are bugs in your scripts which do not allow the connections to shut down (such as infinite loops), the database with only 16 connections may be rapidly swamped.
Persistent connections will usually increase the number of connections open at any given time because idle workers will still hold the connections for the previous requests they served. If a large number of workers is spun up to handle an influx of requests, the connections they opened will remain until the worker is killed or the database server closes the connection.
Ensure that the maximum number of connections allowed by the database server is greater than the maximum number of web request workers (plus any other usage such as crons or administrative connections).
Check your database documentation for information on handling abandoned or idle connections (timeouts). Long timeouts may significantly increase the number of persistent connections open at any one time.
### Potential Drawbacks: Maintaining Connection State
Some database extensions perform automatic cleanup when the connection is reused; others leave this task at the discretion of the application developer. Depending on the chosen database extension and the application design, manual cleanup may be needed before the script exits. Changes that may leave connections in an unexpected state include:
- Selected / default database
- Table locks
- Uncommitted transactions
- Temporary tables
- Connection specific settings or features such as profiling
Table locks and transactions that are not cleaned up or closed may cause other queries to be blocked indefinitely and/or cause subsequent reuse of the connection to cause unexpected changes.
Having the wrong database selected will cause subsequent reuse of the connection to be unable to execute queries as expected (or execute them on the wrong database if schemas are similar enough).
If temporary tables are not cleaned up, subsequent requests will not be able to recreate the same table.
You can implement cleanup using class destructors or [register\_shutdown\_function()](https://www.php.net/manual/en/function.register-shutdown-function.php). You may also want to consider dedicated connection pooling proxies that include this as part of their functionality.
### Final Words
Given their behavior and potential drawbacks described above, you should not use persistent connections without careful consideration. They should not be used without implementing additional changes to your application and careful configuration of your database server and web server and/or PHP-FPM.
Consider alternative solutions such as investigating and fixing the causes of connection creation overheads (for example, disabling reverse DNS lookups on the database server), or dedicated connection pooling proxies.
For high volume web APIs, consider using alternative runtimes or long-running application servers.
### See Also
- [ibase\_pconnect()](https://www.php.net/manual/en/function.ibase-pconnect.php)
- [oci\_pconnect()](https://www.php.net/manual/en/function.oci-pconnect.php)
- [odbc\_pconnect()](https://www.php.net/manual/en/function.odbc-pconnect.php)
- [pfsockopen()](https://www.php.net/manual/en/function.pfsockopen.php)
- [pg\_connect()](https://www.php.net/manual/en/function.pg-connect.php)
- [MySQLi and Persistent Connections](https://www.php.net/manual/en/mysqli.persistconns.php)
- [PDO Connection Management](https://www.php.net/manual/en/pdo.connections.php)
### Found A Problem?
[Learn How To Improve This Page](https://github.com/php/doc-base/blob/master/README.md "This will take you to our contribution guidelines on GitHub") • [Submit a Pull Request](https://github.com/php/doc-en/blob/master/features/persistent-connections.xml) • [Report a Bug](https://github.com/php/doc-en/issues/new?body=From%20manual%20page:%20https:%2F%2Fphp.net%2Ffeatures.persistent-connections%0A%0A---)
[+add a note](https://www.php.net/manual/add-note.php?sect=features.persistent-connections&repo=en&redirect=https://www.php.net/manual/en/features.persistent-connections.php)
### User Contributed Notes 7 notes
[up](https://www.php.net/manual/vote-note.php?id=95340&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=95340&page=features.persistent-connections&vote=down "Vote down!")
22
[***Tom***](https://www.php.net/manual/en/features.persistent-connections.php#95340) [¶](https://www.php.net/manual/en/features.persistent-connections.php#95340)
**16 years ago**
```
There's a third case for PHP: run on a fastCGI interface. In this case, PHP processes are NOT destroyed after each request, and so persistent connections do persist. Set PHP_FCGI_CHILDREN << mysql's max_connections and you'll be fine.
```
[up](https://www.php.net/manual/vote-note.php?id=100009&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=100009&page=features.persistent-connections&vote=down "Vote down!")
14
[***ambrish at php dot net***](https://www.php.net/manual/en/features.persistent-connections.php#100009) [¶](https://www.php.net/manual/en/features.persistent-connections.php#100009)
**15 years ago**
```
In IBM_DB2 extension v1.9.0 or later performs a transaction rollback on persistent connections at the end of a request, thus ending the transaction. This prevents the transaction block from carrying over to the next request which uses that connection if script execution ends before the transaction block does.
```
[up](https://www.php.net/manual/vote-note.php?id=114190&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=114190&page=features.persistent-connections&vote=down "Vote down!")
14
[***php at alfadog dot net***](https://www.php.net/manual/en/features.persistent-connections.php#114190) [¶](https://www.php.net/manual/en/features.persistent-connections.php#114190)
**12 years ago**
```
One additional not regarding odbc_pconnect and possibly other variations of pconnect:
If the connection encounters an error (bad SQL, incorrect request, etc), that error will return with be present in odbc_errormsg for every subsequent action on that connection, even if subsequent actions don't cause another error.
For example:
A script connects with odbc_pconnect.
The connection is created on it's first use.
The script calls a query "Select * FROM Table1".
Table1 doesn't exist and odbc_errormsg contains that error.
Later(days, perhaps), a different script is called using the same parameters to odbc_pconnect.
The connection already exists, to it is reused.
The script calls a query "Select * FROM Table0".
The query runs fine, but odbc_errormsg still returns the error about Table1 not existing.
I'm not seeing a way to clear that error using odbc_ functions, so keep your eyes open for this gotcha or use odbc_connect instead.
```
[up](https://www.php.net/manual/vote-note.php?id=76013&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=76013&page=features.persistent-connections&vote=down "Vote down!")
14
[***christopher dot jones at oracle dot com***](https://www.php.net/manual/en/features.persistent-connections.php#76013) [¶](https://www.php.net/manual/en/features.persistent-connections.php#76013)
**18 years ago**
```
For the oci8 extension it is not true that " [...] when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does.". The oci8 extension does a rollback at the end scripts using persistent connections, thus ending the transaction. The rollback also releases locks. However any ALTER SESSION command (e.g. changing the date format) on a persistent connection will be retained over to the next script.
```
[up](https://www.php.net/manual/vote-note.php?id=89465&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=89465&page=features.persistent-connections&vote=down "Vote down!")
11
[***ynzhang from lakeheadu canada***](https://www.php.net/manual/en/features.persistent-connections.php#89465) [¶](https://www.php.net/manual/en/features.persistent-connections.php#89465)
**17 years ago**
```
It seems that using pg_pconnect() will not persist the temporary views/tables. So if you are trying to create temporary views/tables with the query results and then access them with the next script of the same session, you are out of luck. Those temporary view/tables are gone after each PHP script ended. One way to get around this problem is to create real view/table with session ID as part of the name and record the name&creation time in a common table. Have a garbage collection script to drop the view/table who's session is expired.
```
[up](https://www.php.net/manual/vote-note.php?id=24393&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=24393&page=features.persistent-connections&vote=down "Vote down!")
10
[***jean\_christian at myrealbox dot com***](https://www.php.net/manual/en/features.persistent-connections.php#24393) [¶](https://www.php.net/manual/en/features.persistent-connections.php#24393)
**23 years ago**
```
If anyone ever wonders why the number of idle db process (open connections) seems to grow even though you are using persistent connections, here's why:
"You are probably using a multi-process web server such as Apache. Since
database connections cannot be shared among different processes a new
one is created if the request happen to come to a different web server
child process."
```
[up](https://www.php.net/manual/vote-note.php?id=73370&page=features.persistent-connections&vote=up "Vote up!")
[down](https://www.php.net/manual/vote-note.php?id=73370&page=features.persistent-connections&vote=down "Vote down!")
8
[***andy at paradigm-reborn dot com***](https://www.php.net/manual/en/features.persistent-connections.php#73370) [¶](https://www.php.net/manual/en/features.persistent-connections.php#73370)
**19 years ago**
```
To those using MySQL and finding a lot of leftover sleeping processes, take a look at MySQL's wait_timeout directive. By default it is set to 8 hours, but almost any decent production server will have been lowered to the 60 second range. Even on my testing server, I was having problems with too many connections from leftover persistent connections.
```
[+add a note](https://www.php.net/manual/add-note.php?sect=features.persistent-connections&repo=en&redirect=https://www.php.net/manual/en/features.persistent-connections.php)
- [Features](https://www.php.net/manual/en/features.php)
- [HTTP authentication with PHP](https://www.php.net/manual/en/features.http-auth.php "HTTP authentication with PHP")
- [Cookies](https://www.php.net/manual/en/features.cookies.php "Cookies")
- [Sessions](https://www.php.net/manual/en/features.sessions.php "Sessions")
- [Handling file uploads](https://www.php.net/manual/en/features.file-upload.php "Handling file uploads")
- [Using remote files](https://www.php.net/manual/en/features.remote-files.php "Using remote files")
- [Connection handling](https://www.php.net/manual/en/features.connection-handling.php "Connection handling")
- [Persistent Database Connections](https://www.php.net/manual/en/features.persistent-connections.php "Persistent Database Connections")
- [Command line usage](https://www.php.net/manual/en/features.commandline.php "Command line usage")
- [Garbage Collection](https://www.php.net/manual/en/features.gc.php "Garbage Collection")
- [DTrace Dynamic Tracing](https://www.php.net/manual/en/features.dtrace.php "DTrace Dynamic Tracing")
- [Copyright © 2001-2026 The PHP Documentation Group](https://www.php.net/manual/en/copyright.php)
- [My PHP.net](https://www.php.net/my.php)
- [Contact](https://www.php.net/contact.php)
- [Other PHP.net sites](https://www.php.net/sites.php)
- [Privacy policy](https://www.php.net/privacy.php)
[]()
`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open
Press `Enter` without selection to search using Google |
| Readable Markdown | ### What are Persistent Connections?
Persistent connections are links that do not close when the execution of your script ends. When a persistent connection is requested, PHP checks if there's already an identical persistent connection (that remained open from earlier) - and if it exists, it uses it. If it does not exist, it creates the link. An 'identical' connection is a connection that was opened to the same host, with the same username and the same password (where applicable).
There's no method of requesting a specific connection, or guaranteeing whether you get an existing connection or a brand new one (if all existing connections are in use, or the request is being served by a different worker, which has a separate pool of connections).
This means that you cannot use PHP's persistent connections to, for example:
- assign a specific database session to a specific web user
- create a large transaction across multiple requests
- initiate a query on one request and collect the results on another
Persistent connections do not give you *any* functionality that wasn't possible with non-persistent connections.
### Web Requests
There are two ways in which your web server can utilize PHP to generate web pages:
The first method is to use PHP as a CGI "wrapper". When run this way, an instance of the PHP interpreter is created and destroyed for every page request (for a PHP page) to your web server. Because it is destroyed after every request, any resources that it acquires (such as a link to an SQL database server) are closed when it is destroyed. In this case, you do not gain anything from trying to use persistent connections - they simply don't persist.
The second, and most popular, method is to run PHP-FPM, or PHP as a module in a multiprocess web server, which currently only includes Apache. These setups typically have one process (the parent) which coordinates a set of processes (its children) who actually do the work of serving up web pages. When a request comes in from a client, it is handed off to one of the children that is not already serving another client. This means that when the same client makes a second request to the server, it may be served by a different child process than the first time. When opening a persistent connection, every following page requesting SQL services can reuse the same established connection to the SQL server.
> **Note**:
>
> You can check which method your web requests use by checking the value of "Server API" in the output of [phpinfo()](https://www.php.net/manual/en/function.phpinfo.php) or the value of **`PHP_SAPI`**, run from a web request.
>
> If the Server API is "Apache 2 Handler" or "FPM/FastCGI", then persistent connections will be used across requests served by the same worker. For any other value, persistent connections will not persist after each request.
### Command-line Processes
As command-line PHP uses a new process for each script, persistent connections are not shared between command-line scripts, so there is no value in using them in transient scripts such as crons or commands. However, they may be useful if, for example, you're writing a long-running application server that serves many requests or tasks and each may need their own database connection.
### Why Use Them?
Persistent connections are good if the overhead to create a link to your SQL server is high. Whether or not this overhead is really high depends on many factors. Like, what kind of database it is, whether or not it sits on the same computer on which your web server sits, how loaded the machine the SQL server sits on is and so forth. The bottom line is that if that connection overhead is high, persistent connections help you considerably. They cause the child process to simply connect only once for its entire lifespan, instead of every time it processes a page that requires connecting to the SQL server. This means that for every child that opened a persistent connection will have its own open persistent connection to the server. For example, if you had 20 different child processes that ran a script that made a persistent connection to your SQL server, you'd have 20 different connections to the SQL server, one from each child.
### Potential Drawbacks: Connection Limits
Note, however, that this can have some drawbacks if you are using a database with connection limits that are exceeded by persistent child connections. If your database has a limit of 16 simultaneous connections, and in the course of a busy server session, 17 child threads attempt to connect, one will not be able to. If there are bugs in your scripts which do not allow the connections to shut down (such as infinite loops), the database with only 16 connections may be rapidly swamped.
Persistent connections will usually increase the number of connections open at any given time because idle workers will still hold the connections for the previous requests they served. If a large number of workers is spun up to handle an influx of requests, the connections they opened will remain until the worker is killed or the database server closes the connection.
Ensure that the maximum number of connections allowed by the database server is greater than the maximum number of web request workers (plus any other usage such as crons or administrative connections).
Check your database documentation for information on handling abandoned or idle connections (timeouts). Long timeouts may significantly increase the number of persistent connections open at any one time.
### Potential Drawbacks: Maintaining Connection State
Some database extensions perform automatic cleanup when the connection is reused; others leave this task at the discretion of the application developer. Depending on the chosen database extension and the application design, manual cleanup may be needed before the script exits. Changes that may leave connections in an unexpected state include:
- Selected / default database
- Table locks
- Uncommitted transactions
- Temporary tables
- Connection specific settings or features such as profiling
Table locks and transactions that are not cleaned up or closed may cause other queries to be blocked indefinitely and/or cause subsequent reuse of the connection to cause unexpected changes.
Having the wrong database selected will cause subsequent reuse of the connection to be unable to execute queries as expected (or execute them on the wrong database if schemas are similar enough).
If temporary tables are not cleaned up, subsequent requests will not be able to recreate the same table.
You can implement cleanup using class destructors or [register\_shutdown\_function()](https://www.php.net/manual/en/function.register-shutdown-function.php). You may also want to consider dedicated connection pooling proxies that include this as part of their functionality.
### Final Words
Given their behavior and potential drawbacks described above, you should not use persistent connections without careful consideration. They should not be used without implementing additional changes to your application and careful configuration of your database server and web server and/or PHP-FPM.
Consider alternative solutions such as investigating and fixing the causes of connection creation overheads (for example, disabling reverse DNS lookups on the database server), or dedicated connection pooling proxies.
For high volume web APIs, consider using alternative runtimes or long-running application servers.
### See Also
- [ibase\_pconnect()](https://www.php.net/manual/en/function.ibase-pconnect.php)
- [oci\_pconnect()](https://www.php.net/manual/en/function.oci-pconnect.php)
- [odbc\_pconnect()](https://www.php.net/manual/en/function.odbc-pconnect.php)
- [pfsockopen()](https://www.php.net/manual/en/function.pfsockopen.php)
- [pg\_connect()](https://www.php.net/manual/en/function.pg-connect.php)
- [MySQLi and Persistent Connections](https://www.php.net/manual/en/mysqli.persistconns.php)
- [PDO Connection Management](https://www.php.net/manual/en/pdo.connections.php)
22
[***Tom***](https://www.php.net/manual/en/features.persistent-connections.php#95340) [¶](https://www.php.net/manual/en/features.persistent-connections.php#95340)
**16 years ago**
```
There's a third case for PHP: run on a fastCGI interface. In this case, PHP processes are NOT destroyed after each request, and so persistent connections do persist. Set PHP_FCGI_CHILDREN << mysql's max_connections and you'll be fine.
```
14
[***ambrish at php dot net***](https://www.php.net/manual/en/features.persistent-connections.php#100009) [¶](https://www.php.net/manual/en/features.persistent-connections.php#100009)
**15 years ago**
```
In IBM_DB2 extension v1.9.0 or later performs a transaction rollback on persistent connections at the end of a request, thus ending the transaction. This prevents the transaction block from carrying over to the next request which uses that connection if script execution ends before the transaction block does.
```
14
[***php at alfadog dot net***](https://www.php.net/manual/en/features.persistent-connections.php#114190) [¶](https://www.php.net/manual/en/features.persistent-connections.php#114190)
**12 years ago**
```
One additional not regarding odbc_pconnect and possibly other variations of pconnect:
If the connection encounters an error (bad SQL, incorrect request, etc), that error will return with be present in odbc_errormsg for every subsequent action on that connection, even if subsequent actions don't cause another error.
For example:
A script connects with odbc_pconnect.
The connection is created on it's first use.
The script calls a query "Select * FROM Table1".
Table1 doesn't exist and odbc_errormsg contains that error.
Later(days, perhaps), a different script is called using the same parameters to odbc_pconnect.
The connection already exists, to it is reused.
The script calls a query "Select * FROM Table0".
The query runs fine, but odbc_errormsg still returns the error about Table1 not existing.
I'm not seeing a way to clear that error using odbc_ functions, so keep your eyes open for this gotcha or use odbc_connect instead.
```
14
[***christopher dot jones at oracle dot com***](https://www.php.net/manual/en/features.persistent-connections.php#76013) [¶](https://www.php.net/manual/en/features.persistent-connections.php#76013)
**18 years ago**
```
For the oci8 extension it is not true that " [...] when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does.". The oci8 extension does a rollback at the end scripts using persistent connections, thus ending the transaction. The rollback also releases locks. However any ALTER SESSION command (e.g. changing the date format) on a persistent connection will be retained over to the next script.
```
11
[***ynzhang from lakeheadu canada***](https://www.php.net/manual/en/features.persistent-connections.php#89465) [¶](https://www.php.net/manual/en/features.persistent-connections.php#89465)
**17 years ago**
```
It seems that using pg_pconnect() will not persist the temporary views/tables. So if you are trying to create temporary views/tables with the query results and then access them with the next script of the same session, you are out of luck. Those temporary view/tables are gone after each PHP script ended. One way to get around this problem is to create real view/table with session ID as part of the name and record the name&creation time in a common table. Have a garbage collection script to drop the view/table who's session is expired.
```
10
[***jean\_christian at myrealbox dot com***](https://www.php.net/manual/en/features.persistent-connections.php#24393) [¶](https://www.php.net/manual/en/features.persistent-connections.php#24393)
**23 years ago**
```
If anyone ever wonders why the number of idle db process (open connections) seems to grow even though you are using persistent connections, here's why:
"You are probably using a multi-process web server such as Apache. Since
database connections cannot be shared among different processes a new
one is created if the request happen to come to a different web server
child process."
```
8
[***andy at paradigm-reborn dot com***](https://www.php.net/manual/en/features.persistent-connections.php#73370) [¶](https://www.php.net/manual/en/features.persistent-connections.php#73370)
**19 years ago**
```
To those using MySQL and finding a lot of leftover sleeping processes, take a look at MySQL's wait_timeout directive. By default it is set to 8 hours, but almost any decent production server will have been lowered to the 60 second range. Even on my testing server, I was having problems with too many connections from leftover persistent connections.
``` |
| Shard | 91 (laksa) |
| Root Hash | 2869005436169329891 |
| Unparsed URL | net,php!www,/manual/en/features.persistent-connections.php s443 |